2012-01-18 19 views
15

Corto

Trabajando en el sistema de inicio de sesión y tratando de implementar la función Recordarme.Forma correcta de utilizar la funcionalidad "Recordarme" en PHP

Recientemente, investigué sobre este tema, leí un montón de artículos, publicaciones, historias, novelas, cuentos de hadas (llamándolos así, porque algunos de ellos no contienen ni siquiera 1 línea de código, solo un montón de palabras) aproximadamente, las vulnerabilidades de galletas tales como la fijación, el secuestro ... etc

y decidió para lograr los objetivos siguientes

  1. para establecer el retardo de tiempo entre intentos de conexión (para evitar ataques de fuerza bruta) y al límite de recuento de intentos
  2. Para regenerar la identificación de la sesión en casi todas las operaciones

Pero Realmente me confundí sobre mi problema principal: ¿cuál es la manera adecuada, para la función "recordarme"? usar cookies/sesión/base de datos?

Y por favor explicar su idea en código. (No puedo entender claramente sin código)

detallada

Actualmente, mi código es el que

Durante el inicio de sesión en el que estoy usando siguiente función para configurar las cookies y sesiones

protected function validateUser($userid, $ckey=0, $rememmber=0) { 
    session_start(); 
    session_regenerate_id(true); //this is a security measure 
    $_SESSION['user_id'] = $userid; 
    $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); 
    if (isset($remember) && $rememmber == 'on') { 
     setcookie("user_id", $_SESSION['user_id'], time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/"); 
     setcookie("user_key", sha1($ckey), time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/"); 
    } 
    return true; 
} 

a continuación, en las páginas de usuario seguras, la comprobación de user_id usando user_id a buscar todos los importantes los datos sobre el usuario de db

public function protect() { 
     session_start(); 

     /* Secure against Session Hijacking by checking user agent */ 
     if (isset($_SESSION['HTTP_USER_AGENT'])) { 
      if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) { 
       $this->signout(); 
       exit; 
      } 
     } 

// before we allow sessions, we need to check authentication key - ckey and ctime stored in database 

     /* If session not set, check for cookies set by Remember me */ 
     if (!isset($_SESSION['user_id'])) { 
      if (isset($_COOKIE['user_id']) && isset($_COOKIE['user_key'])) { 
       /* we double check cookie expiry time against stored in database */ 

       $cookie_user_id = $_COOKIE['user_id']; 
           $stmt = $this->db->prepare("select `ckey`,`ctime` from `users` where `id` =?") or die($this->db->error); 
      $stmt->bind_param("i", $cookie_user_id) or die(htmlspecialchars($stmt->error)); 
      $stmt->execute() or die(htmlspecialchars($stmt->error)); 
      $stmt->bind_result($ckey, $ctime) or die($stmt->error); 
      $stmt->close() or die(htmlspecialchars($stmt->error)); 
       // coookie expiry 
       if ((time() - $ctime) > 60 * 60 * 24 * COOKIE_TIME_OUT) { 
        $this->signout(); 
       } 
       /* Security check with untrusted cookies - dont trust value stored in cookie.  
        /* We also do authentication check of the `ckey` stored in cookie matches that stored in database during login */ 

       if (!empty($ckey) && is_numeric($_COOKIE['user_id']) && $_COOKIE['key'] == sha1($ckey)) { 
        session_regenerate_id(); //against session fixation attacks. 

        $_SESSION['user_id'] = $_COOKIE['user_id']; 
        $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); 
       } else { 
        $this->signout(); 
       } 
      } else { 
       if ($page != 'main') { 
        header('Location:' . wsurl); 
        exit(); 
       } 
      } 
     } 
+1

Solo un comentario: desde la perspectiva de UX, creo que es un buen punto que los usuarios sepan si quieres decir "mantenerme conectado" o simplemente "recordar mi identidad". – PapaFreud

+0

Un posible duplicado de: http://stackoverflow.com/questions/244882/what-is-the-best-way-to-implement-remember-me-for-a-website – ThinkingMonkey

+0

@ThinkingMonkey ok, eres genial :) –

Respuesta

2

Pero realmente me confundí acerca de mi problema principal: ¿cuál es el camino correcto, para la función "recordarme"? usar cookies/sesión/base de datos?

Http es una protocall sin estado. El token de autenticación debe permanecer para mantener el estado. La forma correcta es usar la sesión. ¿Ahora cómo rastreas la sesión? Tu decides. Pero las cookies no están mal.

En la sesión puede guardar un hash creado a partir de diferentes criterios del navegador (agente de usuario, sistema operativo, resolución de pantalla, etc.) para comprobar si el token es del mismo entorno. Cuantos más criterios guardes, más difícil será de secuestrar. Por cierto, necesita JavaScript para obtener esta información adicional en todo momento.

+2

Odio la votación negativa, pero 'intente enviarlo por URL (sé que se ve feo) .' - es realmente el objetivo para downvote. Es bien conocido ** vulnerabilidad de ataque de fijación de cookies ** –

3

Si quieres un ejemplo de una función "recuérdame" con el código, se puede retirar mi librería PHP en https://github.com/gbirke/rememberme

+0

Lo tengo funcionar en Firefox. Pero en Chrome tus archivos de prueba no funcionan: se queda en la primera página, no inicia sesión. –

+0

¿Puedo tomar tus 5-10 minutos? por favor agrégueme tural.teyyuboglu en skype –

8

Para establecer el retardo de tiempo entre intentos de conexión (para prevenir ataques de fuerza bruta) y para limitar los intentos de conteo

¿Está proporcionando un método para DOS por cuenta?

para regenerar id de sesión en casi todas las operaciones

erm, no. Es probable que derrote al objeto. Siempre debe generar una nueva identificación cuando la identificación actual ha expirado o cuando el usuario está autenticado; de lo contrario, déjelo en paz.

Pero realmente me confundí acerca de mi problema principal: ¿cuál es el camino correcto, para la función "recordarme"? usar cookies/sesión/base de datos?

Dado que debe conservar un token en el cliente, eso significa cookies (a menos que desee escribir algo realmente complicado con el almacenamiento local). Dado que no desea exponer los datos a través de la cookie/make forgery simple, eso significa que debe ser un valor aleatorio.Y para conciliar el valor aleatorio almacenado, eso significa almacenar datos en el servidor, probablemente en una base de datos, ya que debe ser posible hacer referencia a los datos basados ​​en la identificación del usuario o en base al valor aleatorio.

Si bien podría utilizar una sesión sin vencimiento (o de larga duración), me mantendría alejado de esto - los datos se desvanecerán - y es una buena idea renovar los datos de la sesión de vez en cuando.

También necesita atender el escenario donde un usuario desea que la recuerde en 2 computadoras diferentes. Si solo tiene un token de "recordarme" para cada cuenta, tendrá que usar el mismo valor en ambos clientes o eliminar el token anterior cuando cree uno nuevo (es decir, el usuario solo puede recordarse en una máquina))

por favor explique su idea en el código. No puedo entender claramente sin el código

No. Me pagan para escribir el código; Si quieres que escriba el código para ti, entonces tendrás que pagarme. Y el código ocupará mucho más espacio y tiempo que la descripción anterior.

+3

+1 para obtener una explicación de por qué no escribió el código. –

+0

En esta comunidad, estamos tratando de ayudarnos unos a otros. Soy desarrollador también Solo quería obtener un consejo y un ejemplo de código de su idea, (No soy hablante de inglés. No todas sus publicaciones están 100% claras) De todos modos, gracias por perder su tiempo de forma gratuita :) –

Cuestiones relacionadas