Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

    
            
  •              “No cerrar sesión” - el mejor enfoque                                      12 respuestas                          
  •     
    

Me gustaría añadir un "recuérdame" opción de casilla de verificación antes de iniciar sesión.

¿Cuál es la mejor manera de almacenar de forma segura una cookie en el navegador del usuario?

Por ejemplo, Facebook tienen su casilla de verificación "recuérdame" para que cada vez que entra en facebook.com que ya está en el sistema.

Mi inicio de sesión actual utiliza sesiones simples.

¿Fue útil?

Solución

Esta es una pregunta que muchos, aquí hay algunos enlaces para usted.

Hay también algunos grandes recursos recogidos juntos en la respuesta a esta pregunta: The Definitive autenticación de sitios Web Guía Para

Otros consejos

  

Actualización (13/08/2017) : Para entender por qué estamos separando selector y token, en lugar de usar un token, lea este artículo acerca de la división fichas para prevenir ataques puntuales en consultas SELECT.

Me voy a extraer la estrategia descrita en esta entrada del blog acerca de la autenticación segura a largo plazo ya que cubre una gran cantidad de tierra y sólo estamos interesados ??en el "recuérdame" parte .

Preámbulo - Estructura de base de datos

Queremos una tabla separada de la mesa de nuestros usuarios que tiene este aspecto (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`)
);

Las cosas importantes aquí son que selector y token son campos separados.

después de iniciar sesión

Si usted no tiene random_bytes(), sólo tienes que tomar una copia de 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)
        ]
    );
}

Reautenticación de cargar la página

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

Detalles

Utilizamos 9 bytes de datos aleatorios (base64 12 caracteres) para nuestro selector. Esto proporciona 72 bits de espacio de claves y, por tanto, 2 36 los bits de la resistencia a la colisión (ataques cumpleaños), que es mayor que nuestra capacidad de almacenamiento (integer(11) UNSIGNED) por un factor de 16.

Utilizamos 33 bytes (264 bits) de aleatoriedad para nuestra autenticador real. Esto debería ser impredecible en todos los escenarios prácticos.

almacenar un hash SHA256 del autenticador en la base de datos. Esto mitiga el riesgo de suplantación de usuarios tras la fuga de información.

volver a calcular el hash SHA256 del valor autenticador almacenado en la cookie del usuario y luego compararlo con el hash SHA256 almacenado utilizando hash_equals() para prevenir ataques puntuales.

Nos separa el selector de la autenticador porque las búsquedas de base de datos no son constantes en tiempo. Esto elimina el impacto potencial de fugas de tiempo en búsquedas sin causar un impacto en el rendimiento drástica.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top