Meine Webanwendung verwendet Sitzungen, um nach dem Anmelden Informationen über den Benutzer zu speichern und diese Informationen zu speichern, wenn sie innerhalb der App von Seite zu Seite weitergeleitet werden. In dieser speziellen Anwendung speichere ich den user_id
, first_name
und last_name
der Person.
Ich möchte beim Anmelden die Option "Angemeldet bleiben" anbieten, mit der ein Cookie für zwei Wochen auf dem Computer des Benutzers abgelegt wird. Anschließend wird die Sitzung mit den gleichen Details erneut gestartet, wenn sie zur App zurückkehren.
Was ist der beste Ansatz dafür? Ich möchte ihren user_id
nicht im Cookie speichern, da es so aussieht, als würde es einem Benutzer leicht fallen, die Identität eines anderen Benutzers zu fälschen.
OK, lassen Sie mich das ganz offen sagen: Wenn Sie Benutzerdaten oder von Benutzerdaten abgeleitete Elemente zu diesem Zweck in ein Cookie einfügen, tun Sie etwas Falsches.
Dort. Ich sagte es. Nun können wir zur eigentlichen Antwort übergehen.
Was ist los mit dem Hashing von Benutzerdaten, fragen Sie? Nun, es kommt auf die Belichtungsfläche und die Sicherheit durch Dunkelheit an.
Stellen Sie sich für eine Sekunde vor, Sie wären ein Angreifer. In Ihrer Sitzung wird ein kryptografisches Cookie für die Erinnerung angezeigt. Es ist 32 Zeichen breit. Gee. Das kann ein MD5 sein ...
Stellen wir uns auch für eine Sekunde vor, dass sie den von Ihnen verwendeten Algorithmus kennen. Zum Beispiel:
md5(salt+username+ip+salt)
Jetzt muss ein Angreifer nur noch das "Salz" erzwingen (was eigentlich kein Salz ist, aber dazu später mehr), und er kann jetzt alle gefälschten Token erzeugen, die er will, mit jedem Benutzernamen für seine IP-Adresse! Aber es ist schwer, ein Salz zu erzwingen, oder? Absolut. Aber moderne GPUs sind außerordentlich gut darin. Und wenn Sie nicht genügend Zufälligkeit verwenden (es groß genug machen), wird es schnell fallen und damit die Schlüssel zu Ihrem Schloss.
Kurz gesagt, das einzige, was Sie schützt, ist das Salz, das Sie nicht so gut schützt, wie Sie denken.
Aber warte!
All das wurde vorausgesetzt, dass der Angreifer den Algorithmus kennt! Wenn es geheim und verwirrend ist, dann bist du in Sicherheit, oder? FALSCH. Diese Denkrichtung hat einen Namen: Sicherheit durch Dunkelheit , auf die sich niemals verlassen sollte .
Der bessere Weg
Der bessere Weg besteht darin, die Informationen eines Benutzers, mit Ausnahme der ID, niemals vom Server zu entfernen.
Wenn sich der Benutzer anmeldet, generieren Sie ein großes zufälliges Token (128 bis 256 Bit). Fügen Sie das einer Datenbanktabelle hinzu, die das Token der Benutzer-ID zuordnet, und senden Sie es dann im Cookie an den Client.
Was passiert, wenn der Angreifer das zufällige Token eines anderen Benutzers errät?
Lass uns hier ein bisschen rechnen. Wir generieren ein 128-Bit-Zufallstoken. Das heißt, es gibt:
possibilities = 2^128
possibilities = 3.4 * 10^38
Um zu zeigen, wie absurd diese Zahl ist, stellen wir uns jeden Server im Internet vor (sagen wir heute 50.000.000), der versucht, diese Zahl mit einer Geschwindigkeit von jeweils 1.000.000.000 pro Sekunde zu erzwingen. In der Realität würden Ihre Server unter dieser Last schmelzen, aber lassen Sie uns dies ausprobieren.
guesses_per_second = servers * guesses
guesses_per_second = 50,000,000 * 1,000,000,000
guesses_per_second = 50,000,000,000,000,000
Also 50 Billiarden Vermutungen pro Sekunde. Das ist schnell! Recht?
time_to_guess = possibilities / guesses_per_second
time_to_guess = 3.4e38 / 50,000,000,000,000,000
time_to_guess = 6,800,000,000,000,000,000,000
Also 6,8 Sextillionen Sekunden ...
Versuchen wir, das auf freundlichere Zahlen zu bringen.
215,626,585,489,599 years
Oder noch besser:
47917 times the age of the universe
Ja, das ist das 47917-fache des Zeitalters des Universums ...
Grundsätzlich wird es nicht geknackt werden.
Also zusammenfassend:
Ich empfehle, den Cookie in drei Teilen aufzubewahren.
function onLogin($user) {
$token = GenerateRandomToken(); // generate a token, should be 128 - 256 bit
storeTokenForUser($user, $token);
$cookie = $user . ':' . $token;
$mac = hash_hmac('sha256', $cookie, SECRET_KEY);
$cookie .= ':' . $mac;
setcookie('rememberme', $cookie);
}
Dann, um zu validieren:
function rememberMe() {
$cookie = isset($_COOKIE['rememberme']) ? $_COOKIE['rememberme'] : '';
if ($cookie) {
list ($user, $token, $mac) = explode(':', $cookie);
if (!hash_equals(hash_hmac('sha256', $user . ':' . $token, SECRET_KEY), $mac)) {
return false;
}
$usertoken = fetchTokenByUserName($user);
if (hash_equals($usertoken, $token)) {
logUserIn($user);
}
}
}
Hinweis: Verwenden Sie nicht das Token oder die Kombination aus Benutzer und Token, um einen Datensatz in Ihrer Datenbank zu suchen. Stellen Sie immer sicher, dass Sie einen Datensatz basierend auf dem Benutzer abrufen und eine zeitsichere Vergleichsfunktion verwenden, um das abgerufene Token anschließend zu vergleichen. Mehr über Timing-Attacken .
Nun ist es sehr wichtig, dass der SECRET_KEY
ein kryptografisches Geheimnis ist (generiert durch etwas wie /dev/urandom
und/oder abgeleitet von a Eingabe mit hoher Entropie). Außerdem muss GenerateRandomToken()
eine starke Zufallsquelle sein (mt_Rand()
ist bei weitem nicht stark genug. Verwenden Sie eine Bibliothek wie RandomLib oder random_compat oder mcrypt_create_iv()
mit DEV_URANDOM
) ...
Die hash_equals()
soll Timing-Attacken verhindern. Wenn Sie eine PHP Version unter PHP 5.6 verwenden, wird die Funktion hash_equals()
nicht unterstützt. In diesem Fall können Sie hash_equals()
durch die timingSafeCompare-Funktion ersetzen:
/**
* A timing safe equals comparison
*
* To prevent leaking length information, it is important
* that user input is always used as the second parameter.
*
* @param string $safe The internal (safe) value to be checked
* @param string $user The user submitted (unsafe) value
*
* @return boolean True if the two strings are identical.
*/
function timingSafeCompare($safe, $user) {
if (function_exists('hash_equals')) {
return hash_equals($safe, $user); // PHP 5.6
}
// Prevent issues if string length is 0
$safe .= chr(0);
$user .= chr(0);
// mbstring.func_overload can make strlen() return invalid numbers
// when operating on raw binary strings; force an 8bit charset here:
if (function_exists('mb_strlen')) {
$safeLen = mb_strlen($safe, '8bit');
$userLen = mb_strlen($user, '8bit');
} else {
$safeLen = strlen($safe);
$userLen = strlen($user);
}
// Set the result to the difference between the lengths
$result = $safeLen - $userLen;
// Note that we ALWAYS iterate over the user-supplied length
// This is to prevent leaking length information
for ($i = 0; $i < $userLen; $i++) {
// Using % here is a trick to prevent notices
// It's safe, since if the lengths are different
// $result is already non-0
$result |= (ord($safe[$i % $safeLen]) ^ ord($user[$i]));
}
// They are only identical strings if $result is exactly 0...
return $result === 0;
}
Sicherheitshinweis: Es ist keine gute Idee, den Cookie von einem MD5-Hash mit deterministischen Daten abzugrenzen. Es ist besser, ein zufälliges Token zu verwenden, das von einem CSPRNG abgeleitet ist. Siehe Antwort von ircmaxell zu dieser Frage für einen sichereren Ansatz.
Normalerweise mache ich so etwas:
Natürlich können Sie verschiedene Cookie-Namen usw. verwenden. Sie können auch den Inhalt des Cookies ein wenig ändern. Stellen Sie nur sicher, dass er nicht so einfach erstellt werden kann. Sie können zum Beispiel auch eine user_salt erstellen, wenn der Benutzer erstellt wird, und dies auch in das Cookie setzen.
Sie können auch sha1 anstelle von md5 verwenden (oder so ziemlich jeden Algorithmus).
Einführung
Ihr Titel “Keep me eingeloggt” - der beste Ansatz macht es mir schwer zu wissen, wo ich anfangen soll. Wenn Sie den besten Ansatz suchen, müssen Sie Folgendes berücksichtigen:
Kekse
Cookies sind anfällig. Zwischen häufigen Browser-Cookie-Diebstahl-Sicherheitsanfälligkeiten und Cross-Site-Scripting-Angriffen müssen wir akzeptieren, dass Cookies nicht sicher sind. Zur Verbesserung der Sicherheit müssen Sie beachten, dass php
setcookies
über zusätzliche Funktionen verfügt, z
bool setcookie (Zeichenfolge $ name [ Zeichenfolge $ value [ int $ expire = 0 [ Zeichenfolge $ path [ Zeichenfolge $ domain [ bool $ secure = false [ bool $ httponly = false]]]]]])
Definitionen
Einfacher Ansatz
Eine einfache Lösung wäre:
Die obige Fallstudie fasst alle Beispiele zusammen, die auf dieser Seite aufgeführt sind, aber ihre Nachteile liegen darin
Bessere Lösung
Eine bessere Lösung wäre
Beispielcode
// Set privateKey
// This should be saved securely
$key = 'fc4d57ed55a78de1a7b31e711866ef5a2848442349f52cd470008f6d30d47282';
$key = pack("H*", $key); // They key is used in binary form
// Am Using Memecahe as Sample Database
$db = new Memcache();
$db->addserver("127.0.0.1");
try {
// Start Remember Me
$rememberMe = new RememberMe($key);
$rememberMe->setDB($db); // set example database
// Check if remember me is present
if ($data = $rememberMe->auth()) {
printf("Returning User %s\n", $data['user']);
// Limit Acces Level
// Disable Change of password and private information etc
} else {
// Sample user
$user = "baba";
// Do normal login
$rememberMe->remember($user);
printf("New Account %s\n", $user);
}
} catch (Exception $e) {
printf("#Error %s\n", $e->getMessage());
}
Verwendete Klasse
class RememberMe {
private $key = null;
private $db;
function __construct($privatekey) {
$this->key = $privatekey;
}
public function setDB($db) {
$this->db = $db;
}
public function auth() {
// Check if remeber me cookie is present
if (! isset($_COOKIE["auto"]) || empty($_COOKIE["auto"])) {
return false;
}
// Decode cookie value
if (! $cookie = @json_decode($_COOKIE["auto"], true)) {
return false;
}
// Check all parameters
if (! (isset($cookie['user']) || isset($cookie['token']) || isset($cookie['signature']))) {
return false;
}
$var = $cookie['user'] . $cookie['token'];
// Check Signature
if (! $this->verify($var, $cookie['signature'])) {
throw new Exception("Cokies has been tampared with");
}
// Check Database
$info = $this->db->get($cookie['user']);
if (! $info) {
return false; // User must have deleted accout
}
// Check User Data
if (! $info = json_decode($info, true)) {
throw new Exception("User Data corrupted");
}
// Verify Token
if ($info['token'] !== $cookie['token']) {
throw new Exception("System Hijacked or User use another browser");
}
/**
* Important
* To make sure the cookie is always change
* reset the Token information
*/
$this->remember($info['user']);
return $info;
}
public function remember($user) {
$cookie = [
"user" => $user,
"token" => $this->getRand(64),
"signature" => null
];
$cookie['signature'] = $this->hash($cookie['user'] . $cookie['token']);
$encoded = json_encode($cookie);
// Add User to database
$this->db->set($user, $encoded);
/**
* Set Cookies
* In production enviroment Use
* setcookie("auto", $encoded, time() + $expiration, "/~root/",
* "example.com", 1, 1);
*/
setcookie("auto", $encoded); // Sample
}
public function verify($data, $hash) {
$Rand = substr($hash, 0, 4);
return $this->hash($data, $Rand) === $hash;
}
private function hash($value, $Rand = null) {
$Rand = $Rand === null ? $this->getRand(4) : $Rand;
return $Rand . bin2hex(hash_hmac('sha256', $value . $Rand, $this->key, true));
}
private function getRand($length) {
switch (true) {
case function_exists("mcrypt_create_iv") :
$r = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
break;
case function_exists("openssl_random_pseudo_bytes") :
$r = openssl_random_pseudo_bytes($length);
break;
case is_readable('/dev/urandom') : // deceze
$r = file_get_contents('/dev/urandom', false, null, 0, $length);
break;
default :
$i = 0;
$r = "";
while($i ++ < $length) {
$r .= chr(mt_Rand(0, 255));
}
break;
}
return substr(bin2hex($r), 0, $length);
}
}
Testen in Firefox und Chrome
Vorteil
Nachteil
Schnelle Lösung
Mehrfach-Cookie-Ansatz
Wenn ein Angreifer Cookies stiehlt, konzentrieren Sie sich nur auf eine bestimmte Website oder Domäne, z. example.com
Aber wirklich, Sie können einen Benutzer von zwei verschiedenen Domains (example.com & fakeaddsite.com) authentifizieren und ihn wie "Advert Cookie" aussehen lassen.
Einige Leute fragen sich vielleicht, wie Sie zwei verschiedene Cookies verwenden können. Nun, es ist möglich, stellen Sie sich example.com = localhost
und fakeaddsite.com = 192.168.1.120
vor. Wenn Sie die Cookies betrachten, würde es so aussehen
Aus dem Bild oben
192.168.1.120
HTTP_REFERER
REMOTE_ADDR
Vorteil
Nachteil
Verbesserung
ajax
Es gibt zwei sehr interessante Artikel, die ich auf der Suche nach einer perfekten Lösung für das "Remember-Me" -Problem gefunden habe:
Ich habe einen Blickwinkel dieser Frage gestellt here , und die Antworten werden Sie zu allen tokenbasierten Timeout-Cookie-Links führen, die Sie benötigen.
Grundsätzlich speichern Sie die userId nicht im Cookie. Sie speichern ein einmaliges Token (riesige Zeichenfolge), mit dem der Benutzer seine alte Anmeldesitzung abholt. Um es wirklich sicher zu machen, müssen Sie ein Kennwort für schwere Vorgänge (wie das Ändern des Kennworts selbst) anfordern.
Ich würde das von Stefan erwähnte Vorgehen empfehlen (dh den Richtlinien in Verbesserte beständige Login-Cookie-Best Practice folgen) und auch empfehlen, sicherzustellen, dass Ihre Cookies HttpOnly-Cookies sind damit sie nicht für potenziell böswillige Personen zugänglich sind , JavaScript.
Alter Thread, aber immer noch ein berechtigtes Anliegen. Ich habe einige gute Reaktionen auf die Sicherheit festgestellt und die Verwendung von "Sicherheit durch Unklarheit" vermieden, aber die tatsächlichen technischen Methoden waren für mich nicht ausreichend. Dinge, die ich sagen muss, bevor ich meine Methode einbringe:
Alles in allem gibt es zwei großartige Möglichkeiten, ein automatisches Signing auf Ihrem System durchzuführen.
Erstens, der günstige, einfache Weg, der alles auf jemand anderen legt. Wenn Sie Ihren Site-Support mit Ihrem Google + -Konto anmelden, sagen Sie, zB Ihr Google + -Konto, haben Sie wahrscheinlich eine optimierte Google + -Schaltfläche, mit der sich der Benutzer anmelden wird, wenn er bereits bei Google angemeldet ist (ich habe das hier getan, um diese Frage zu beantworten, da ich es immer bin.) bei google angemeldet). Wenn Sie möchten, dass der Benutzer automatisch angemeldet wird, wenn er bereits mit einem vertrauenswürdigen und unterstützten Authentifikator angemeldet ist, und das Kontrollkästchen aktiviert ist, müssen die clientseitigen Skripts vor dem Laden den Code hinter der entsprechenden Schaltfläche "Anmelden mit" ausführen Stellen Sie sicher, dass der Server eine eindeutige ID in einer Tabelle für das automatische Signieren speichert, die den Benutzernamen, die Sitzungs-ID und den für den Benutzer verwendeten Authentifikator enthält. Da diese Anmeldemethoden AJAX verwenden, warten Sie trotzdem auf eine Antwort, und diese Antwort ist entweder eine validierte Antwort oder eine Ablehnung. Wenn Sie eine validierte Antwort erhalten, verwenden Sie sie wie gewohnt und laden Sie den angemeldeten Benutzer dann normal weiter. Andernfalls ist die Anmeldung fehlgeschlagen, teilen Sie dem Benutzer jedoch nicht mit, sondern fahren Sie fort, da er nicht angemeldet ist. Dadurch soll verhindert werden, dass ein Angreifer, der Cookies gestohlen hat (oder bei einem Versuch, die Berechtigungen zu erhöhen, gefälscht wurde), erfährt, dass der Benutzer sich automatisch bei der Site anmeldet.
Dies ist billig und wird von manchen als schmutzig betrachtet, da versucht wird, Ihr möglicherweise bereits angemeldetes Eigenes bei Orten wie Google und Facebook zu überprüfen, ohne Sie darüber zu informieren. Es sollte jedoch nicht für Benutzer verwendet werden, die nicht aufgefordert haben, Ihre Site automatisch zu signieren. Diese spezielle Methode dient nur zur externen Authentifizierung, wie bei Google+ oder FB.
Da ein externer Authentifikator verwendet wurde, um dem Server hinter den Kulissen mitzuteilen, ob ein Benutzer überprüft wurde oder nicht, kann ein Angreifer nur eine eindeutige ID erhalten, die alleine unbrauchbar ist. Ich werde ausarbeiten:
Diese Methode kann und sollte in Verbindung mit Ihrem internen Authentifikator für Benutzer verwendet werden, die sich über einen externen Authentifikator bei Ihrer Site anmelden.
=========.
Nun, für Ihr eigenes Authentifizierungssystem, das Benutzer automatisch signieren kann, mache ich es so:
DB hat einige Tabellen:
TABLE users:
UID - auto increment, PK
username - varchar(255), unique, indexed, NOT NULL
password_hash - varchar(255), NOT NULL
...
TABLE sessions: session_id - varchar(?), PK session_token - varchar(?), NOT NULL session_data - MediumText, NOT NULL
.TABLE autologin: UID - auto increment, PK username - varchar(255), NOT NULL, allow duplicates hostname - varchar(255), NOT NULL, allow duplicates mac_address - char(23), NOT NULL, unique token - varchar(?), NOT NULL, allow duplicates expires - datetime code
Dadurch wird verhindert, dass jemand systematisch den MAC und den Hostnamen eines Benutzers spoofet, für den er automatische Signaturen kennt. NEVER Der Benutzer muss ein Cookie mit seinem Kennwort, Klartext oder auf andere Weise aufbewahren. Lassen Sie das Token auf jeder Seitennavigation neu generieren, genau wie Sie das Sitzungstoken tun würden. Dies verringert massiv die Wahrscheinlichkeit, dass ein Angreifer ein gültiges Token-Cookie erhält und zur Anmeldung verwendet. Einige Leute versuchen zu sagen, dass ein Angreifer die Cookies des Opfers stehlen und einen Sitzungswiederholungsangriff durchführen kann, um sich anzumelden. Wenn ein Angreifer die Cookies stehlen könnte (was möglich ist), hätte er sicherlich das gesamte Gerät gefährdet, was bedeutet, dass er das Gerät ohnehin nur zum Anmelden verwenden könnte, was den Zweck des vollständigen Diebstahls von Cookies verhindert. Solange Ihre Site über HTTPS läuft (was bei Passwörtern, CC-Nummern oder anderen Anmeldesystemen der Fall sein sollte), haben Sie dem Benutzer so viel Schutz geboten, wie Sie innerhalb eines Browsers können.
Beachten Sie Folgendes: Sitzungsdaten sollten bei Verwendung der automatischen Anmeldung nicht verfallen. Sie können nicht mehr die Möglichkeit haben, die Sitzung falsch fortzusetzen, aber bei einer Überprüfung im System sollten die Sitzungsdaten wieder aufgenommen werden, wenn es sich um persistente Daten handelt, die voraussichtlich zwischen den Sitzungen fortgesetzt werden. Wenn Sie sowohl persistente als auch nicht persistente Sitzungsdaten wünschen, verwenden Sie eine andere Tabelle für persistente Sitzungsdaten mit dem Benutzernamen als PK, und lassen Sie den Server diese wie normale Sitzungsdaten abrufen. Verwenden Sie einfach eine andere Variable.
Wenn auf diese Weise eine Anmeldung erfolgt ist, sollte der Server die Sitzung weiterhin überprüfen. Hier können Sie Erwartungen für gestohlene oder kompromittierte Systeme kodieren. Muster und andere erwartete Ergebnisse von Anmeldungen bei Sitzungsdaten können häufig zu Schlussfolgerungen führen, dass ein System missbraucht wurde oder Cookies erstellt wurden, um Zugriff zu erhalten. Hier kann Ihr ISS - Techniker Regeln festlegen, die eine Kontosperrung oder das automatische Entfernen eines Benutzers aus dem Auto-Signin-System auslösen, sodass Angreifer lange genug vom Angreifer ferngehalten werden, um zu ermitteln, wie der Angreifer erfolgreich war und wie Schneid Sie ab.Als Abschlussnotiz sollten Sie sicherstellen, dass alle Wiederherstellungsversuche, Kennwortänderungen oder Anmeldungsfehler nach dem Schwellenwert dazu führen, dass die automatische Anmeldung deaktiviert wird, bis der Benutzer die Gültigkeit überprüft und bestätigt, dass dies geschehen ist.
Ich entschuldige mich, wenn jemand erwartet hat, dass der Code in meiner Antwort ausgegeben wird. Dies wird hier nicht passieren. Ich werde sagen, dass ich PHP, jQuery und AJAX verwende, um meine Sites zu betreiben, und ich nutze NIEMALS Windows als Server ... überhaupt.
As a closing note, be sure that any recovery attempt, password changes, or login failures past the threshold result in auto-signin being disabled until the user validates properly and acknowledges this has occurred.
I apologize if anyone was expecting code to be given out in my answer, that's not going to happen here. I will say that I use PHP, jQuery, and AJAX to run my sites, and I NEVER use Windows as a server... ever.
Erzeugen Sie einen Hash, vielleicht mit einem Geheimnis, das Sie nur kennen, und speichern Sie es in Ihrer Datenbank, damit es dem Benutzer zugeordnet werden kann. Sollte ganz gut funktionieren.
Ich verstehe das Konzept des Speicherns von verschlüsseltem Material in einem Cookie nicht, wenn es sich um die verschlüsselte Version des Cookies handelt, die Sie zum Hacken benötigen. Wenn mir etwas fehlt, bitte kommentieren.
Ich denke darüber nach, diesen Ansatz zu "Remember Me" zu verwenden. Wenn Sie Probleme sehen, kommentieren Sie bitte.
Erstellen Sie eine Tabelle, in der "Remember Me" -Daten gespeichert werden - getrennt von der Benutzertabelle, damit ich mich von mehreren Geräten aus anmelden kann.
Bei erfolgreichem Login (mit Remember me ankreuzen):
a) Erzeugen Sie eine eindeutige zufällige Zeichenfolge, die als Benutzer-ID auf diesem Computer verwendet werden soll: bigUserID
b) Erzeugen Sie einen eindeutigen zufälligen String: bigKey
c) Speichern Sie einen Cookie: bigUserID: bigKey
d) Fügen Sie in der Tabelle "Remember Me" einen Datensatz hinzu mit: UserID, IP-Adresse, bigUserID, bigKey
Wenn Sie versuchen, auf etwas zuzugreifen, für das ein Login erforderlich ist:
a) Suchen Sie nach dem Cookie und suchen Sie nach bigUserID & bigKey mit einer übereinstimmenden IP-Adresse
b) Wenn Sie es finden, melden Sie die Person an, setzen Sie jedoch ein Kennzeichen in der Benutzertabelle "Soft-Login", damit Sie bei gefährlichen Vorgängen eine vollständige Anmeldung anfordern können.
Markieren Sie beim Abmelden alle "Remember Me" -Datensätze für diesen Benutzer als abgelaufen.
Die einzigen Schwachstellen, die ich sehen kann, sind:
Meine Lösung ist so. Es ist nicht 100% kugelsicher, aber ich denke, es wird Sie für die meisten Fälle retten.
Wenn der Benutzer sich erfolgreich angemeldet hat, erstellen Sie eine Zeichenfolge mit diesen Informationen:
$data = (SALT + ":" + hash(User Agent) + ":" + username
+ ":" + LoginTimestamp + ":"+ SALT)
$data
verschlüsseln, Typ auf HttpOnly setzen und Cookie setzen.
Wenn der Benutzer zu Ihrer Site zurückkehrt, führen Sie folgende Schritte aus:
:
Zeichen. Wenn sich der Benutzer abmeldet, entfernen Sie dieses Cookie. Erstellen Sie ein neues Cookie, wenn sich der Benutzer erneut anmeldet.
Ich las alle Antworten und fand es immer noch schwierig herauszufinden, was ich tun sollte. Wenn ein Bild 1-k-Wörter wert ist, hoffe ich, dass dies anderen hilft, einen sicheren dauerhaften Speicher zu implementieren, der auf Barry Jaspans Improved Persistent Login Cookie Best Practice basiert.
Wenn Sie Fragen, Rückmeldungen oder Vorschläge haben, werde ich versuchen, das Diagramm zu aktualisieren, damit der Neuling versucht, eine sichere persistente Anmeldung zu implementieren.
Das Implementieren einer Funktion "Angemeldet bleiben" bedeutet, dass Sie genau definieren müssen, was dies für den Benutzer bedeutet. Im einfachsten Fall würde ich damit sagen, dass die Sitzung viel länger dauert: 2 Tage (sagen wir) anstatt 2 Stunden. Dazu benötigen Sie Ihren eigenen Sitzungsspeicher, wahrscheinlich in einer Datenbank, um benutzerdefinierte Ablaufzeiten für die Sitzungsdaten festzulegen. Dann müssen Sie sicherstellen, dass Sie ein Cookie setzen, das einige Tage (oder länger) verbleibt und nicht abläuft, wenn der Browser geschlossen wird.
Ich höre Sie fragen "Warum 2 Tage? Warum nicht 2 Wochen?". Dies liegt daran, dass bei Verwendung einer Sitzung in PHP der Ablauf automatisch zurückgeschoben wird. Dies liegt daran, dass das Ablaufdatum einer Sitzung in PHP tatsächlich ein Timeout ist.
Nachdem ich das gesagt habe, würde ich wahrscheinlich einen härteren Timeout-Wert implementieren, den ich in der Sitzung selbst und nach etwa zwei Wochen abspeichere. Dann füge ich Code hinzu, um das zu sehen und die Sitzung zwangsweise ungültig zu machen. Oder zumindest um sie abzumelden. Dies bedeutet, dass der Benutzer regelmäßig aufgefordert wird, sich anzumelden. Yahoo! macht dies.