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.

War es hilfreich?

Andere Tipps

  

Update (2017.08.13) : Um zu verstehen, warum wir selector und token sind zu trennen, anstatt nur einen token 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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top