python - ¿Cómo caducar la sesión debido a la inactividad en Django?
login django python (6)
En la primera solicitud, puede establecer la caducidad de la sesión como
self.request.session[''access_key''] = access_key
self.request.session[''access_token''] = access_token
self.request.session.set_expiry(set_age) #in seconds
Y cuando se usa access_key y token,
try:
key = self.request.session[''access_key'']
except KeyError:
age = self.request.session.get_expiry_age()
if age > set_age:
#redirect to login page
Nuestra aplicación Django tiene los siguientes requisitos de gestión de sesión.
- Las sesiones caducan cuando el usuario cierra el navegador.
- Las sesiones caducan después de un período de inactividad.
- Detecta cuando una sesión caduca debido a inactividad y muestra el mensaje apropiado al usuario.
- Advierta a los usuarios sobre la expiración de una sesión inminente unos minutos antes del final del período de inactividad. Junto con la advertencia, brinde a los usuarios la opción de extender su sesión.
- Si el usuario está trabajando en una actividad comercial larga dentro de la aplicación que no implica solicitudes que se envían al servidor, la sesión no debe exceder el tiempo de espera.
Después de leer la documentación, el código de Django y algunas publicaciones de blog relacionadas con esto, he presentado el siguiente enfoque de implementación.
Requisito 1
Este requisito se implementa fácilmente al establecer SESSION_EXPIRE_AT_BROWSER_CLOSE en True.
Requisito 2
He visto algunas recomendaciones para usar SESSION_COOKIE_AGE para establecer el período de vencimiento 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á utilizando activamente la aplicación. (Esto puede evitarse configurando el vencimiento de la sesión en SESSION_COOKIE_AGE en cada solicitud utilizando 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 en el navegador cerrado o en el tiempo de caducidad especificado. Si se usa SESSION_COOKIE_AGE y el usuario cierra el navegador antes de que caduque, la cookie se conserva y la reapertura del navegador permitirá al usuario (o a cualquier otra persona) ingresar al sistema sin volver a autenticarse.
Django confía solo en la cookie presente para determinar si la sesión está activa. No verifica la fecha de caducidad de la sesión almacenada con la sesión.
El siguiente método podría utilizarse para implementar este requisito y resolver los problemas mencionados anteriormente.
- No establezca SESSION_COOKIE_AGE.
- Establezca la fecha de caducidad de la sesión como ''tiempo actual + período de inactividad'' en cada solicitud.
- Anule la solicitud de proceso en SessionMiddleware y verifique la caducidad de la sesión. Deseche la sesión si ha expirado.
Requisito 3
Cuando detectamos que la sesión ha expirado (en el SessionMiddleware personalizado anterior), configure un atributo en la solicitud para indicar el vencimiento de la sesión. Este atributo se puede usar para mostrar un mensaje apropiado al usuario.
Requisito 4
Use JavaScript para detectar la inactividad del usuario, proporcione la advertencia y también una opción para extender la sesión. Si el usuario desea extender, 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 activo 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 idea será muy apreciada.
Soy bastante nuevo para usar Django.
Quería que la sesión caducara si el usuario registrado cerraba el navegador o estaba inactivo (tiempo de inactividad) durante algún tiempo. Cuando busqué en Google para descubrirlo, esta pregunta SOF surgió primero. Gracias a una buena respuesta, busqué recursos para comprender cómo funciona middlewares durante el ciclo de solicitud / respuesta en Django. Fue muy útil.
Estaba a punto de aplicar middleware personalizado en mi código después de la respuesta superior aquí. Pero todavía estaba un poco sospechoso porque la mejor respuesta aquí fue editada en 2011. Me tomé más tiempo para buscar un poco de los resultados de búsqueda recientes y se me ocurrió de manera simple.
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_AGE = 10 # set just 10 seconds to test
SESSION_SAVE_EVERY_REQUEST = True
No revisé otros navegadores, pero sí Chrome. 1. Una sesión expiró cuando cerré un navegador incluso si SESSION_COOKIE_AGE configuró. 2. Solo cuando estaba inactivo por más de 10 segundos, una sesión expiró. Gracias a SESSION_SAVE_EVERY_REQUEST, cada vez que se produce una nueva solicitud, se guarda la sesión y se agota el tiempo de espera de las actualizaciones
Para cambiar este comportamiento predeterminado, establezca 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 crea o modifica una sesión. Si SESSION_SAVE_EVERY_REQUEST es True, la cookie de sesión se enviará en cada solicitud.
Del mismo modo, la parte de caducidad de una cookie de sesión se actualiza cada vez que se envía la cookie de sesión.
Simplemente dejo la respuesta para que algunas personas que son una novedad en Django como yo no pasen mucho tiempo buscando la solución como lo hice.
Una manera fácil de satisfacer su segundo requisito sería establecer el valor de SESSION_COOKIE_AGE en settings.py en una cantidad adecuada de segundos. Por ejemplo:
SESSION_COOKIE_AGE = 600 #10 minutes.
Sin embargo, al solo hacer esto, la sesión caducará después de 10 minutos ya sea que el usuario muestre alguna actividad o no. Para resolver este problema, el tiempo de caducidad se puede renovar automáticamente (por otros 10 minutos adicionales) cada vez que el usuario realice cualquier tipo de solicitud con la siguiente frase:
request.session.set_expiry(request.session.get_expiry_age())
también puedes usar build en funciones
SESSION_SAVE_EVERY_REQUEST = True
django-session-security hace precisamente eso ...
... con un requisito adicional: si el servidor no responde o si un atacante desconectó la conexión a Internet: debe caducar de todos modos.
Descargo de responsabilidad: mantengo esta aplicación. Pero he estado viendo este hilo durante mucho, mucho tiempo :)
Aquí hay una idea ... Caduque la sesión al cerrar el navegador con la configuración SESSION_EXPIRE_AT_BROWSER_CLOSE
. A continuación, establezca una marca de tiempo en la sesión en cada solicitud como tal.
request.session[''last_activity''] = datetime.now()
y agregue un middleware para detectar si la sesión ha expirado. algo así debe manejar todo el proceso ...
from datetime import datetime
from django.http import HttpResponseRedirect
class SessionExpiredMiddleware:
def process_request(request):
last_activity = request.session[''last_activity'']
now = datetime.now()
if (now - last_activity).minutes > 10:
# Do logout / expire session
# and then...
return HttpResponseRedirect("LOGIN_PAGE_URL")
if not request.is_ajax():
# don''t set this for ajax requests or else your
# expired session checks will keep the session from
# expiring :)
request.session[''last_activity''] = now
Luego solo tiene que hacer algunas 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 establecer requeset.session[''last_activity'']
a la hora actual de nuevo
Obviamente, este código es solo un comienzo ... pero debería llevarlo por el camino correcto