2011-05-10 8 views
6

Según Persistent Login Cookie Best Practice, nunca se debe permitir que un "Remember Me" contadores a usarse más de una vez:Condición Carrera por "Remember Me" cookies persistentes

Una cookie persistente es bueno para un único inicio de sesión. Cuando se confirma la autenticación, se invalida el número aleatorio utilizado para iniciar sesión y se asigna una nueva cookie. La gestión de sesión estándar maneja las credenciales durante la vida de la sesión, por lo que la cookie recién asignada no se verificará hasta la próxima sesión (en ese momento, también se invalidará después de su uso).

Entonces, ¿cómo se maneja la condición de carrera cuando un usuario visita múltiples URL en su sitio al mismo tiempo? En realidad estoy teniendo este problema ahora.

Digamos que se envían dos solicitudes desde el navegador al servidor al mismo tiempo. Las solicitudes no contienen cookies de sesión, sino la misma cookie "recordarme". Una de las solicitudes se manejará antes que la otra, y recibirá una respuesta con una cookie de sesión autenticada y una cookie regenerada de "recordarme".

El "recuérdame" token en la segunda solicitud está ahora invalidado y otro identificador de sesión se genera en el servidor. Esta solicitud falla, ya que el usuario no puede ser autenticado.

He encontrado algunas posibles soluciones, pero ninguna de ellas parece muy buena. ¿Me estoy perdiendo de algo?

+0

Estoy comenzando a darme cuenta de que el problema se debe a que http es apátrida. Si el token "recordarme" no se invalidara de inmediato, las respuestas seguirían devolviendo sesiones diferentes (y el navegador sobrescribiría las sesiones anteriores con la última). –

Respuesta

2

Pregunta anterior pero no encontré la respuesta en ningún lado. Tuve el mismo problema. Mi solución fue almacenar el token antiguo en la base de datos y usarlo como respaldo si no se encuentra el token principal. Pero me aseguré de que el token viejo solo sea válido para un marco de tiempo corto, como varios segundos después de que cambie el token. Entonces solo cambio el token si ha pasado algún tiempo desde la actualización anterior, de lo contrario habrá casos en que el token cambie varias veces seguidas.

1

Para explicar la respuesta de vangoz, debo agregar que también se debe emplear algún tipo de mecanismo de bloqueo. Considere esto pseudocódigo PHP-ish aquí:

if (isFallback($token)) { 
    // Log the user in 
} else { 
    // Usual processing 
    // If token has to be updated, save old token as fallback for a few seconds 
} 

Cuando hay solicitudes simultáneas que podrían terminar tanto en la rama más, una solicitud hará que la actualización y el otro hará que el token a ser invalidado. La forma en que resolvió esto fue usar un bloqueo con nombre, llamado después del $token en cuestión, para envolver la rama else. Además, todas las solicitudes simultáneas excepto una no podrán adquirir el bloqueo, en cuyo caso dormiremos un poco y volveremos a intentar (al reintentarlo, veremos que el token se ha convertido en un token de reserva).

if (isFallback($token)) { 
    // Log the user in 
} else { 
    $couldLock = lock($token); 
    if (!$couldLock) { 
    usleep(10000); 
    // Retry, possibly a recursive call 
    } else { 
    // Usual processing 
    // If token has to be updated, save old token as fallback for a few seconds 
    unlock($token); 
    } 
} 

espero que estas consideraciones pueden ser útiles.

Cuestiones relacionadas