Domanda

    

Questa domanda ha già una risposta qui:

    
            
  •              “Resta collegato” - l'approccio migliore                                      12 risposte                          
  •     
    

Vorrei aggiungere un "Ricordati di me" opzione casella di controllo prima di accedere.

Qual è il modo migliore per archiviare in modo sicuro un cookie nel browser dell'utente?

Per esempio, Facebook hanno il loro casella di controllo "ricordati di me", in modo che ogni volta che si entra facebook.com si è già connessi a.

Il mio login corrente utilizza le sessioni semplici.

È stato utile?

Soluzione

Questa domanda viene chiesto molto, ecco alcuni link per voi.

Ci sono anche alcune grandi risorse raccolte insieme nella risposta a questa domanda: The Definitive Guide all'autenticazione Sito

Altri suggerimenti

  

Aggiornamento (2017/08/13) : Per capire il motivo per cui stiamo separando selector e token, invece di utilizzare un token, si prega di leggere questo articolo su splitting gettoni per prevenire attacchi di temporizzazione su query SELECT.

ho intenzione di estrarre la strategia delineata in questo post del blog a proposito di garantire a lungo termine l'autenticazione dato che copre un sacco di terra e siamo interessati solo nel "ricordati di me" parte .

Preambolo - Struttura del database

Vogliamo un tavolo separato dalla tavola dei nostri utenti che assomiglia a questo (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`)
);

Le cose importanti sono che selector e token sono campi separati.

Dopo l'accesso

Se non si dispone di random_bytes(), basta prendere una copia di 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-Autenticazione On caricamento della pagina

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
    }
}

Dettagli

Usiamo 9 byte di dati casuali (base64 codificato a 12 caratteri) per il nostro selettore. Questo fornisce 72 bit di spazio delle chiavi e quindi 2 36 bit di resistenza collisione (attacco del compleanno), che è più grande della nostra capacità di stoccaggio (integer(11) UNSIGNED) per un fattore di 16.

Usiamo 33 byte (264 bit) di casualità per il nostro autenticatore effettivo. Questo dovrebbe essere imprevedibile in tutti gli scenari pratici.

memorizzare un hash SHA256 del autenticatore nel database. Questo riduce il rischio di rappresentazione utente a seguito di perdite di informazioni.

Abbiamo ri-calcolare l'hash SHA256 del valore autenticatore memorizzato nel cookie dell'utente poi confrontarlo con l'hash SHA256 memorizzato utilizzando hash_equals() per prevenire attacchi di temporizzazione.

separava il selettore dalla autenticatore perché ricerche DB non sono a tempo costante. Questo elimina la potenziale impatto delle perdite di sincronizzazione su ricerche senza causare un calo di prestazioni drastica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top