112 votes

Comment expirer une session pour cause d'inactivité dans Django ?

Notre application Django a les exigences suivantes en matière de gestion des sessions.

  1. Les sessions expirent lorsque l'utilisateur ferme son navigateur.
  2. Les sessions expirent après une période d'inactivité.
  3. Détecter l'expiration d'une session pour cause d'inactivité et afficher un message approprié à l'utilisateur.
  4. Prévenez les utilisateurs de l'expiration imminente de leur session quelques minutes avant la fin de la période d'inactivité. En même temps que l'avertissement, offrez aux utilisateurs la possibilité de prolonger leur session.
  5. Si l'utilisateur travaille sur une longue activité professionnelle dans l'application qui n'implique pas l'envoi de requêtes au serveur, la session ne doit pas expirer.

Après avoir lu la documentation, le code de Django et quelques articles de blog à ce sujet, j'ai trouvé l'approche de mise en œuvre suivante.

Exigence 1
Cette exigence est facilement mise en œuvre en donnant à SESSION_EXPIRE_AT_BROWSER_CLOSE la valeur True.

Exigence 2
J'ai vu quelques recommandations d'utiliser SESSION_COOKIE_AGE pour définir la période d'expiration de la session. Mais cette méthode présente les problèmes suivants.

  • La session expire toujours à la fin du SESSION_COOKIE_AGE, même si l'utilisateur utilise activement l'application. (On peut éviter ce problème en fixant l'expiration de la session à SESSION_COOKIE_AGE à chaque demande à l'aide d'un intergiciel personnalisé ou en sauvegardant la session à chaque demande en fixant SESSION_SAVE_EVERY_REQUEST à true. Mais le problème suivant est inévitable en raison de l'utilisation de SESSION_COOKIE_AGE).

  • En raison du fonctionnement des cookies, SESSION_EXPIRE_AT_BROWSER_CLOSE et SESSION_COOKIE_AGE s'excluent mutuellement, c'est-à-dire que le cookie expire soit à la fermeture du navigateur, soit à l'heure d'expiration spécifiée. Si SESSION_COOKIE_AGE est utilisé et que l'utilisateur ferme le navigateur avant l'expiration du cookie, le cookie est conservé et la réouverture du navigateur permettra à l'utilisateur (ou à toute autre personne) d'accéder au système sans être réauthentifié.

  • Django se fie uniquement à la présence du cookie pour déterminer si la session est active. Il ne vérifie pas la date d'expiration de la session stockée avec celle-ci.

La méthode suivante pourrait être utilisée pour mettre en œuvre cette exigence et contourner les problèmes mentionnés ci-dessus.

  • Ne pas définir SESSION_COOKIE_AGE.
  • Définissez la date d'expiration de la session comme étant "l'heure actuelle + la période d'inactivité" à chaque demande.
  • Remplacer process_request dans SessionMiddleware et vérifier l'expiration de la session. Abandonnez la session si elle a expiré.

Exigence 3
Lorsque nous détectons que la session a expiré (dans le SessionMiddleware personnalisé ci-dessus), nous définissons un attribut sur la demande pour indiquer l'expiration de la session. Cet attribut peut être utilisé pour afficher un message approprié à l'utilisateur.

Exigence 4
Utilisez JavaScript pour détecter l'inactivité de l'utilisateur, lui adresser un avertissement et lui proposer une option de prolongation de la session. Si l'utilisateur souhaite prolonger la session, envoyez une impulsion de maintien en vie au serveur pour prolonger la session.

Exigence 5
Utilisez JavaScript pour détecter l'activité de l'utilisateur (pendant les longues opérations commerciales) et envoyez des impulsions de maintien en vie au serveur pour empêcher l'expiration de la session.


L'approche de mise en œuvre ci-dessus semble très élaborée et je me demandais s'il n'y avait pas une méthode plus simple (en particulier pour l'exigence 2).

Tout commentaire sera très apprécié.

3 votes

+1 pour avoir fourni une solution détaillée

0 votes

Il existe un intergiciel qui peut faire ce dont vous avez besoin. sur github y sur pypi

1 votes

"En raison du mode de fonctionnement des cookies, SESSION_EXPIRE_AT_BROWSER_CLOSE et SESSION_COOKIE_AGE s'excluent mutuellement, c'est-à-dire que le cookie expire soit à la fermeture du navigateur, soit à l'heure d'expiration spécifiée. Si SESSION_COOKIE_AGE est utilisé et que l'utilisateur ferme le navigateur avant l'expiration du cookie, le cookie est conservé et la réouverture du navigateur permettra à l'utilisateur (ou à toute autre personne) d'accéder au système sans être réauthentifié." Corrigez-moi si je me trompe, mais cela ne semble plus être vrai dans les nouvelles versions de Django ? (1.5+ au moins)

4voto

tilaprimera Points 136

Dans la première demande, vous pouvez définir l'expiration de la session comme suit

self.request.session['access_key'] = access_key
self.request.session['access_token'] = access_token
self.request.session.set_expiry(set_age) #in seconds 

Et en utilisant la clé d'accès et le jeton,

try:
    key = self.request.session['access_key']
except KeyError:
    age = self.request.session.get_expiry_age()
    if age > set_age:
        #redirect to login page

3voto

gbutler Points 82

Il existe un intergiciel qui peut faire ce dont vous avez besoin. sur github et sur pypi

0voto

CleberAP Points 1

J'utilise Django 3.2 et je recommande l'utilisation de l'option django-auto-logout paquet.

Il permet de contrôler les sessions de temps actif et de temps mort.

Dans le modèle, vous pouvez utiliser des variables avec du Javascript.

0 votes

Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien à titre de référence. Les réponses ne comportant qu'un lien peuvent devenir invalides si la page liée change. - De la revue

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X