Menú
Está libre
registrarse
el principal  /  Firmware/ Ver inicio de sesión recuérdame semana. Cómo funciona

Ver inicio de sesión recuérdame semana. Cómo funciona

Dado que hemos planteado este tema, me gustaría recordarle cómo mejorar la implementación de la función estándar de recordarme.

Ambas opciones propuestas anteriormente no tienen en cuenta una punto importante¿Qué pasa si te roban la ficha? Con la implementación habitual de autenticación a través del token de recordarme, el atacante, habiendo recibido dicho token, obtendrá acceso al sitio por un tiempo ilimitado y la víctima ni siquiera sabrá sobre el robo ...

¿Qué hacer?

Barry Jaspan ha desarrollado una autenticación de recordarme mejorada.

En resumen, se agrega otro tipo de token: serie. Debe generarlo de forma aleatoria, como un token normal. La principal diferencia entre este y el token es que no cambia después de una autenticación exitosa a través del token.

Mesa de almacenamiento:
CREATE TABLE test.one_time_auth (token CHAR (32), serie CHAR (32), user_id INT (11) UNSIGNED NOT NULL, expire DATETIME DEFAULT NULL, PRIMARY KEY (series)) ENGINE = INNODB
Y una clase con un ejemplo
setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ auth = new one_time_auth ($ db); lista ($ token, $ serie) = $ auth-> recordar (10, nulo, "2010-12-31"); $ user_id = $ auth-> recordar ($ token, $ serie); lista ($ token, $ serie) = $ auth-> recordar (10, $ serie, "2010-12-31"); $ user_id = $ auth-> recordar ($ token, $ serie); echo $ user_id; lista ($ token, $ serie) = $ auth-> recordar (10, $ serie, "2010-12-31"); try ($ user_id = $ auth-> remind ("wrongone", $ series);) catch (ThiefAssumedException $ e) (echo "Creemos que su cookie fue robada. Por favor, inicie sesión de nuevo.";) $ user_id = $ auth -> recordar ("incorrecto", "incorrecto"); // no hacer nada class ThiefAssumedException extiende Exception () class one_time_auth (/ ** * @var PDO * / private $ db; función pública __construct (PDO $ db) ($ this-> db = $ db;) función pública recordar ($ user_id, $ series = null, $ expire = null) ($ sql = "INSERT INTO one_time_auth (token, serie, user_id, expire) VALUES (: token ,: series ,: user_id ,: expire)"; $ stmt = $ this -> db-> prepare ($ sql); while (true) (try ($ stmt-> execute (array (": token" => $ token = $ this-> generateToken (), ": series" => $ series = $ series == null? $ this-> generateToken (): $ series, "user_id" => $ user_id, "expire" => $ expire)); break;) catch (PDOException $ e) ()) return array ($ token, $ series);) función pública recordar ($ token, $ series) ($ sql = "SELECT user_id, token FROM one_time_auth WHERE series =: series AND (expire IS NULL OR expire> = NOW ()) LIMIT 1 "; $ stmt = $ this-> db-> prepare ($ sql); $ stmt-> execute (array (" serie "=> $ serie)); if ($ fila = $ stmt-> fetch ()) (if ($ fila ["token"]! = $ toke n) ($ stmt = $ this-> db-> prepare ("ELIMINAR DE one_time_auth DONDE user_id =: user_id"); $ stmt-> execute (array ("user_id" => $ fila ["user_id"])); lanzar nueva ThiefAssumedException (); ) $ stmt = $ this-> db-> prepare ("ELIMINAR DE one_time_auth DONDE series =: series"); $ stmt-> ejecutar (matriz ("serie" => $ serie)); return $ fila ["user_id"]; )) función privada generateToken () (return md5 (uniqid ("", verdadero));))

¿Cómo funciona?

El token y la serie del usuario se guardan en cookies, el script los compara con los proporcionados en la base de datos. Si coinciden, la autenticación se realiza correctamente. El usuario recibe un nuevo token con la serie anterior. Si el token es diferente, pero la serie es la misma, borramos todos los registros de recordarme para esta cuenta e informamos al usuario que, tal vez, su token fue robado.

Ps: esta no es una solución lista para usar, sino un ejemplo.

Dado que hemos planteado este tema, me gustaría recordarle cómo mejorar la implementación de la función estándar de recordarme.

Ambas opciones sugeridas anteriormente no tienen en cuenta un punto importante, ¿qué pasa si el token es robado? Con la implementación habitual de autenticación a través del token de recordarme, el atacante, habiendo recibido dicho token, obtendrá acceso al sitio por un tiempo ilimitado y la víctima ni siquiera sabrá sobre el robo ...

¿Qué hacer?

Barry Jaspan ha desarrollado una autenticación de recordarme mejorada.

En resumen, se agrega otro tipo de token: serie. Debe generarlo de forma aleatoria, como un token normal. La principal diferencia entre este y el token es que no cambia después de una autenticación exitosa a través del token.

Mesa de almacenamiento:
CREATE TABLE test.one_time_auth (token CHAR (32), serie CHAR (32), user_id INT (11) UNSIGNED NOT NULL, expire DATETIME DEFAULT NULL, PRIMARY KEY (series)) ENGINE = INNODB
Y una clase con un ejemplo
setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ auth = new one_time_auth ($ db); lista ($ token, $ serie) = $ auth-> recordar (10, nulo, "2010-12-31"); $ user_id = $ auth-> recordar ($ token, $ serie); lista ($ token, $ serie) = $ auth-> recordar (10, $ serie, "2010-12-31"); $ user_id = $ auth-> recordar ($ token, $ serie); echo $ user_id; lista ($ token, $ serie) = $ auth-> recordar (10, $ serie, "2010-12-31"); try ($ user_id = $ auth-> remind ("wrongone", $ series);) catch (ThiefAssumedException $ e) (echo "Creemos que su cookie fue robada. Por favor, inicie sesión de nuevo.";) $ user_id = $ auth -> recordar ("incorrecto", "incorrecto"); // no hacer nada class ThiefAssumedException extiende Exception () class one_time_auth (/ ** * @var PDO * / private $ db; función pública __construct (PDO $ db) ($ this-> db = $ db;) función pública recordar ($ user_id, $ series = null, $ expire = null) ($ sql = "INSERT INTO one_time_auth (token, serie, user_id, expire) VALUES (: token ,: series ,: user_id ,: expire)"; $ stmt = $ this -> db-> prepare ($ sql); while (true) (try ($ stmt-> execute (array (": token" => $ token = $ this-> generateToken (), ": series" => $ series = $ series == null? $ this-> generateToken (): $ series, "user_id" => $ user_id, "expire" => $ expire)); break;) catch (PDOException $ e) ()) return array ($ token, $ series);) función pública recordar ($ token, $ series) ($ sql = "SELECT user_id, token FROM one_time_auth WHERE series =: series AND (expire IS NULL OR expire> = NOW ()) LIMIT 1 "; $ stmt = $ this-> db-> prepare ($ sql); $ stmt-> execute (array (" serie "=> $ serie)); if ($ fila = $ stmt-> fetch ()) (if ($ fila ["token"]! = $ toke n) ($ stmt = $ this-> db-> prepare ("ELIMINAR DE one_time_auth DONDE user_id =: user_id"); $ stmt-> execute (array ("user_id" => $ fila ["user_id"])); lanzar nueva ThiefAssumedException (); ) $ stmt = $ this-> db-> prepare ("ELIMINAR DE one_time_auth DONDE series =: series"); $ stmt-> ejecutar (matriz ("serie" => $ serie)); return $ fila ["user_id"]; )) función privada generateToken () (return md5 (uniqid ("", verdadero));))

¿Cómo funciona?

El token y la serie del usuario se guardan en cookies, el script los compara con los proporcionados en la base de datos. Si coinciden, la autenticación se realiza correctamente. El usuario recibe un nuevo token con la serie anterior. Si el token es diferente, pero la serie es la misma, borramos todos los registros de recordarme para esta cuenta e informamos al usuario que, tal vez, su token fue robado.

Ps: esta no es una solución lista para usar, sino un ejemplo.