PHP Login-System: Remember Me (persistente Cookie) [Duplikat]
-
01-10-2019 - |
Frage
Diese Frage bereits eine Antwort hier:
- „Angemeldet bleiben“ - der beste Ansatz 12 Antworten
Ich möchte eine "remember me" Checkbox Option hinzufügen, bevor Sie sich anmelden.
Was ist der beste Weg, um sicher ein Cookie speichert in dem Browser des Benutzers?
Zum Beispiel hat Facebook ihre „remember me“ aktivieren, so dass jedes Mal, wenn Sie facebook.com geben Sie bereits angemeldet sind.
Meine aktuelle Login verwendet einfache Sitzungen.
Lösung
Diese Frage viel gefragt wird, hier einige Links für Sie.
- Best Practice Implementierung eines sicheren „Remember Me“
- „Erinnere mich an diesem Computer“ - Wie sollte es funktionieren?
- „Angemeldet bleiben“ - der beste Ansatz
Es gibt auch einige große Ressourcen zusammen auf diese Frage in der Antwort gesammelt: The Definitive Guide To Website-Authentifizierung
Andere Tipps
Update (2017.08.13) : Um zu verstehen, warum wir
selector
undtoken
sind zu trennen, anstatt nur einentoken
verwenden, lesen Sie Token dieser Artikel über Splitting Timing-Attacken auf SELECT-Abfragen zu verhindern.
Ich werde die Strategie in diesem Blog-Eintrag erläutert extrahieren über langfristig gesicherte Authentifizierung da, dass viele von Bodendeckern und wir sind nur in der "remember me" Teil.
Präambel - Datenbankstruktur
Wir wollen eine separate Tabelle aus unserer Nutzer Tisch sieht wie folgt aus (MySQL):
CREATE TABLE `auth_tokens` (
`id` integer(11) not null UNSIGNED AUTO_INCREMENT,
`selector` char(12),
`token` char(64),
`userid` integer(11) not null UNSIGNED,
`expires` datetime,
PRIMARY KEY (`id`)
);
Die wichtigen Dinge hier sind, dass selector
und token
sind separate Felder aus.
Nach der Anmeldung
Wenn Sie nicht random_bytes()
haben, greifen nur eine Kopie von random_compat .
if ($login->success && $login->rememberMe) { // However you implement it
$selector = base64_encode(random_bytes(9));
$authenticator = random_bytes(33);
setcookie(
'remember',
$selector.':'.base64_encode($authenticator),
time() + 864000,
'/',
'yourdomain.com',
true, // TLS-only
true // http-only
);
$database->exec(
"INSERT INTO auth_tokens (selector, token, userid, expires) VALUES (?, ?, ?, ?)",
[
$selector,
hash('sha256', $authenticator),
$login->userId,
date('Y-m-d\TH:i:s', time() + 864000)
]
);
}
Re-Authentifizierung beim Laden der Seite
if (empty($_SESSION['userid']) && !empty($_COOKIE['remember'])) {
list($selector, $authenticator) = explode(':', $_COOKIE['remember']);
$row = $database->selectRow(
"SELECT * FROM auth_tokens WHERE selector = ?",
[
$selector
]
);
if (hash_equals($row['token'], hash('sha256', base64_decode($authenticator)))) {
$_SESSION['userid'] = $row['userid'];
// Then regenerate login token as above
}
}
Details
Wir verwenden 9 Byte Zufallsdaten (Base64 codiert zu 12 Zeichen) für unsere Wähler. Dies stellt 72 Bits des Schlüsselraumes und damit 2 36 Bits Kollisionswiderstand (Geburtstag Attacken), die um den Faktor 16 größer als unsere Speicherkapazität (integer(11) UNSIGNED
) ist.
Wir verwenden 33 Bytes (264 Bits) der Zufälligkeit für unsere tatsächliche Authenticator. Dies sollte in allen praktischen Szenarien unberechenbar sein.
Wir speichern einen SHA256 Hash-Wert des Authenticator in der Datenbank. Dies mildert das Risiko von Benutzeridentitätswechsel folgende Daten in falsche Hände.
Wir neu berechnen, die SHA256 Hash-Wert des Wertes Authenticator im Cookie des Benutzers gespeichert dann vergleichen mit dem SHA256 Hash gespeichert sind hash_equals()
Timing-Angriffe zu verhindern.
Wir trennten die Wähler von dem Authenticator, weil DB-Lookups nicht konstante Zeit. Dies beseitigt die möglichen Auswirkungen der Zeit Lecks auf Durchsuchungen ohne eine drastische Leistungseinbußen verursacht.