Nuestra aplicación Django tiene los siguientes requisitos de gestión de sesiones.
- Las sesiones caducan cuando el usuario cierra el navegador.
- Las sesiones caducan después de un período de inactividad.
- Detecta cuándo caduca una sesión debido a la inactividad y muestra el mensaje correspondiente al usuario.
- Advierta a los usuarios sobre el vencimiento de una sesión inminente unos minutos antes del final del período de inactividad. Junto con la advertencia, brinde a los usuarios una opción para extender su sesión.
- Si el usuario está trabajando en una actividad comercial prolongada dentro de la aplicación que no implica el envío de solicitudes al servidor, la sesión no debe expirar.
Después de leer la documentación, el código Django y algunas publicaciones de blog relacionadas con esto, se me ocurrió el siguiente enfoque de implementación.
Requisito 1
Este requisito se implementa fácilmente estableciendo SESSION_EXPIRE_AT_BROWSER_CLOSE en True.
Requisito 2
He visto algunas recomendaciones para usar SESSION_COOKIE_AGE para establecer el período de caducidad de la sesión. Pero este método tiene los siguientes problemas.
La sesión siempre expira al final de SESSION_COOKIE_AGE incluso si el usuario está usando la aplicación de forma activa. (Esto se puede evitar configurando el vencimiento de la sesión en SESSION_COOKIE_AGE en cada solicitud usando un middleware personalizado o guardando la sesión en cada solicitud configurando SESSION_SAVE_EVERY_REQUEST en verdadero. Pero el siguiente problema es inevitable debido al uso de SESSION_COOKIE_AGE).
Debido a la forma en que funcionan las cookies, SESSION_EXPIRE_AT_BROWSER_CLOSE y SESSION_COOKIE_AGE son mutuamente excluyentes, es decir, la cookie caduca al cerrar el navegador o en el tiempo de caducidad especificado. Si se utiliza SESSION_COOKIE_AGE y el usuario cierra el navegador antes de que caduque la cookie, la cookie se retiene y la reapertura del navegador permitirá que el usuario (o cualquier otra persona) ingrese al sistema sin volver a autenticarse.
Django se basa solo en la presencia de la cookie para determinar si la sesión está activa. No verifica la fecha de vencimiento de la sesión almacenada con la sesión.
El siguiente método podría utilizarse para implementar este requisito y solucionar los problemas mencionados anteriormente.
- No establezca SESSION_COOKIE_AGE.
- Establezca la fecha de vencimiento de la sesión en 'tiempo actual + período de inactividad' en cada solicitud.
- Anule process_request en SessionMiddleware y compruebe la expiración de la sesión. Descarte la sesión si ha expirado.
Requisito 3
Cuando detectamos que la sesión ha expirado (en el SessionMiddleware personalizado anterior), establezca un atributo en la solicitud para indicar la expiración de la sesión. Este atributo se puede utilizar para mostrar un mensaje apropiado al usuario.
Requisito 4
Utilice JavaScript para detectar la inactividad del usuario, proporcionar la advertencia y también una opción para extender la sesión. Si el usuario desea extender la sesión, envíe un pulso de mantener vivo al servidor para extender la sesión.
Requisito 5
Utilice JavaScript para detectar la actividad del usuario (durante la operación comercial prolongada) y envíe impulsos de mantener vivo al servidor para evitar que la sesión expire.
El enfoque de implementación anterior parece muy elaborado y me preguntaba si podría haber un método más simple (especialmente para el Requisito 2).
Cualquier información será muy apreciada.
Respuestas:
Aquí tienes una idea ... Expira la sesión al cerrar el navegador con la
SESSION_EXPIRE_AT_BROWSER_CLOSE
configuración. Luego, establezca una marca de tiempo en la sesión para cada solicitud como esa.y agregue un middleware para detectar si la sesión ha expirado. algo como esto debería manejar todo el proceso ...
Luego, solo tiene que crear algunas direcciones URL y vistas para devolver datos relevantes a las llamadas ajax con respecto al vencimiento de la sesión.
cuando el usuario opta por "renovar" la sesión, por así decirlo, todo lo que tiene que hacer es
requeset.session['last_activity']
volver a configurar la hora actualObviamente, este código es solo el comienzo ... pero debería llevarlo por el camino correcto
fuente
if not request.is_ajax()
sea completamente seguro. ¿No puede alguien que se apodere de la sesión antes de la expiración de la suplantación de identidad / enviar una llamada ajax y mantener la sesión?Soy bastante nuevo en el uso de Django.
Quería hacer que la sesión expirara si el usuario registrado cierra el navegador o está inactivo (tiempo de espera de inactividad) durante algún tiempo. Cuando busqué en Google para averiguarlo, esta pregunta SOF surgió primero. Gracias a la buena respuesta, busqué recursos para comprender cómo funcionan los middlewares durante el ciclo de solicitud / respuesta en Django. Fue muy útil.
Estaba a punto de aplicar middleware personalizado en mi código siguiendo la respuesta principal aquí. Pero todavía sospechaba un poco porque la mejor respuesta aquí se editó en 2011. Me tomé más tiempo para buscar un poco en los resultados de búsqueda recientes y se me ocurrió una forma simple.
No revisé otros navegadores sino Chrome. 1. Una sesión expiró cuando cerré un navegador incluso si se configuró SESSION_COOKIE_AGE. 2. Solo cuando estuve inactivo durante más de 10 segundos, una sesión expiró. Gracias a SESSION_SAVE_EVERY_REQUEST, cada vez que se produce una nueva solicitud, guarda la sesión y actualiza el tiempo de espera para que expire
Para cambiar este comportamiento predeterminado, establezca la configuración SESSION_SAVE_EVERY_REQUEST en True. Cuando se establece en True, Django guardará la sesión en la base de datos en cada solicitud.
Tenga en cuenta que la cookie de sesión solo se envía cuando se ha creado o modificado una sesión. Si SESSION_SAVE_EVERY_REQUEST es True, la cookie de sesión se enviará en cada solicitud.
De manera similar, la parte de caducidad de una cookie de sesión se actualiza cada vez que se envía la cookie de sesión.
manual de django 1.10
Solo dejo la respuesta para que algunas personas que son algo nuevas en Django como yo no dediquen mucho tiempo a encontrar una solución como lo hice yo.
fuente
django-session-security hace precisamente eso ...
... con un requisito adicional: si el servidor no responde o un atacante desconecta la conexión a Internet: debería caducar de todos modos.
Descargo de responsabilidad: mantengo esta aplicación. Pero he estado viendo este hilo durante mucho, mucho tiempo :)
fuente
Una forma fácil de satisfacer su segundo requisito sería establecer el valor SESSION_COOKIE_AGE en settings.py en una cantidad adecuada de segundos. Por ejemplo:
Sin embargo, con solo hacer esto, la sesión expirará después de 10 minutos, ya sea que el usuario muestre alguna actividad o no. Para solucionar este problema, el tiempo de caducidad se puede renovar automáticamente (por otros 10 minutos más) cada vez que el usuario realiza algún tipo de solicitud con la siguiente frase:
fuente
SESSION_COOKIE_AGE
es suficiente y que cualquier solicitud (enviar la cookie de sesión) actualizará automáticamente el vencimiento de la cookie de sesión.también puede usar funciones integradas de stackoverflow
fuente
En la primera solicitud, puede establecer la caducidad de la sesión como
Y al usar la clave de acceso y el token,
fuente