root/docs/trunk/sessions.txt

Revision 342, 19.5 kB (checked in by anhj, 2 years ago)

Update : authentication.txt r8506, django-admin.txt r8548, generic-views.txt r8506, middleware.txt r8506, sessions.txt r8506, templates.txt r8557

Line 
1 =============================
2 Comment utiliser les sessions
3 =============================
4
5 Django fournit un support complet de sessions anonymes. Le systÚme de sessions
6 vous permet de stocker et de retrouver les données que vous souhaitez par
7 visiteur de votre site. Il stocke les données cÎté serveur et fournit une couche
8 d'abstraction pour l'envoi et la réception des cookies. Les cookies contiennent
9 une ID de session -- pas les données elles-mêmes.
10
11 Mise en place des sessions
12 ==========================
13
14 Les sessions sont mises en place via un middleware_.
15
16 Pour mettre en place la fonctionnalité de sessions, faites ce qui suit :
17
18     * Editez la variable de réglage ``MIDDLEWARE_CLASSES`` et assurez vous
19       qu'elle contient
20       ``'django.contrib.sessions.middleware.SessionMiddleware'``. C'est déjà le
21       cas dans le fichier ``settings.py`` créé par Django par défaut.
22
23     * Ajoutez ``'django.contrib.sessions'`` à la variable ``INSTALLED_APPS``, et
24       exécutez ``manage.py syncdb`` pour installer la table qui stocke les
25       données de session dans la base de données.
26
27       **Nouveau dans la version de développement :** cette étape n'est pas
28       obligatoire si vous n'utilisez pas le backend de sessions de la base de
29       données, voir `configuration du moteur de sessions`_.
30
31 Si vous ne souhaitez pas utiliser les sessions, vous pouvez retirer la ligne
32 ``SessionMiddleware`` de ``MIDDLEWARE_CLASSES`` et ``'django.contrib.sessions'``
33 de ``INSTALLED_APPS``. Cela épargnera un peu de travail à votre Django.
34
35 .. _middleware: ../middleware/
36
37 Configuration du moteur de sessions
38 ===================================
39
40 **Nouveau dans la version de développement**
41
42 Par défaut, Django stocke les données de session en base de données (en
43 utilisant le modÚle ``django.contrib.sessions.models.Session``). Bien que cela
44 soit pratique, il existe des cas dans lesquels il est plus rapide de stocker les
45 données de session ailleurs, et Django peut être configuré pour utiliser le
46 systÚme de fichier ou le cache à cet effet.
47
48 Utiliser des sessions basées sur un fichier
49 -------------------------------------------
50
51 Pour utiliser des sessions dont les données sont stockées dans un fichier,
52 donnez au réglage ``SESSION_ENGINE`` la valeur
53 ``django.contrib.sessions.backends.file``.
54
55 Vous pouvez aussi utiliser le réglage ``SESSION_FILE_PATH`` (dont la valeur par
56 défaut est fournie par ``tempfile.gettempdir()``, soit probablement ``/tmp``)
57 pour contrÎler l'endroit où Django placera les fichiers de session.
58 Assurez-vous que votre serveur Web a les permissions nécessaires pour lire et
59 écrire à cet emplacement.
60
61 Utiliser des sessions basées sur le cache
62 -----------------------------------------
63
64 Pour stocker les données de session en utilisant le systÚme de cache de Django,
65 donnez au réglage ``SESSION_ENGINE`` la valeur
66 ``django.contrib.sessions.backends.cache``. Assurez-vous d'avoir configuré votre
67 cache correctement, voyez la `documentation du cache`_ pour plus de détails.
68
69 .. _documentation du cache: ../cache/
70
71 .. note::
72
73     Vous ne devriez probablement utiliser des sessions basées sur le cache que
74     si votre systÚme de cache est Memcached. Le backend de cache en mémoire
75     locale ne conserve pas les données suffisamment longtemps pour
76     être un bon choix, et il est plus rapide d'avoir directement des sessions
77     utilisant le systÚme de fichiers ou la base de données que d'avoir des
78     backends de cache en base de données ou en fichier.
79
80 Utiliser les sessions dans les vues
81 ===================================
82
83 Quand ``SessionMiddleware`` est activé, chaque objet ``HttpRequest`` -- le
84 premier argument de toutes les fonctions vues de Django -- aura un attribut
85 ``session``, qui est un objet de type dictionnaire. Vous pouvez le lire et y
86 écrire.
87
88 Un objet session possÚde les méthodes standards de dictionnaires suivantes :
89
90     * ``__getitem__(key)``
91
92       Exemple: ``fav_color = request.session['fav_color']``
93
94     * ``__setitem__(key, value)``
95
96       Exemple: ``request.session['fav_color'] = 'blue'``
97
98     * ``__delitem__(key)``
99
100       Exemple: ``del request.session['fav_color']``. LÚve l'exception ``KeyError``
101       si la clé ``key`` n'existe pas déjà dans la session.
102
103     * ``__contains__(key)``
104
105       Exemple: ``'fav_color' in request.session``
106
107     * ``get(key, default=None)``
108
109       Exemple: ``fav_color = request.session.get('fav_color', 'red')``
110
111     * ``keys()``
112
113     * ``items()``
114
115     * ``setdefault()`` (**Nouveau dans la version de développement de Django**)
116
117     * ``clear()`` (**Nouveau dans la version de développement de Django**)
118
119 Il possÚde aussi ces méthodes :
120
121     * ``flush()``
122
123       **Nouveau dans la version de développement de Django**
124
125       Efface les données de la session courante de la base de données et
126       régénÚre la valeur de la clé de session qui est renvoyée à l'utilisateur
127       dans un cookie. A utiliser si vous voulez vous assurer que les
128       données de la session précédente ne peuvent pas être accessible à
129       nouveau à partir du navigateur de l'utilisateur (par exemple, la
130       méthode ``django.contrib.auth.logout()`` l'utilise).
131
132     * ``set_test_cookie()``
133
134       Place un cookie de test pour vérifier que le navigateur de l'utilisateur
135       accepte les cookies. Compte tenu du mode de fonctionnement des cookies, on
136       ne peut pas le tester avant la prochaine requête de l'utilisateur. Voir
137       `Mise en place de cookies de test`_ ci-dessous pour plus d'informations.
138
139     * ``test_cookie_worked()``
140
141           Renvoie ``True`` si le navigateur de l'utilisateur a accepté le cookie de
142           test, ``False`` sinon. En raison du mode de fonctionnement des cookies,
143           vous devrez appeler ``set_test_cookie()`` sur une page précédente appelée
144           dans une autre requête. Voir `Mise en place de cookies de test`_
145           ci-dessous pour plus d'informations.
146
147     * ``delete_test_cookie()``
148
149       Efface le cookie de test. Utilisez cette fonction pour faire le ménage
150       aprÚs le test.
151
152         * ``set_expiry(value)``
153
154           **Nouveau dans la version de développement de Django**
155
156           Positionne la date d'expiration de la session. Vous pouvez passer
157           les valeurs de façon différente :
158
159           * Si ``value`` est un entier, la session expirera aprÚs ce nombre
160             de secondes d'inactivité. Par exemple, appeller
161             ``request.session.set_expiry(300)`` fera se terminer la session
162             aprÚs 5 minutes d'inactivité.
163
164           * Si ``value`` est un objet ``datetime`` ou ``timedelta``, la session
165             expirera à la date et l'heure spécifiées.
166
167           * Si ``value`` est ``0``, la session de l'utilisateur expirera lorsque
168             le navigateur de l'utilisateur sera fermé.
169
170           * Si ``value`` est ``None``, la session utilisera la politique
171             globale d'expiration des sessions.
172
173         * ``get_expiry_age()``
174
175           **Nouveau dans la version de développement de Django**
176
177           Renvoie le nombre de secondes avant l'expiration de cette session. Pour
178           les sessions sans date d'expiration spécifique (ou celles qui expirent
179           à la fermeture du navigateur), la valeur renvoyée vaudra
180           ``settings.SESSION_COOKIE_AGE``.
181
182         * ``get_expiry_date()``
183
184           **Nouveau dans la version de développement de Django**
185
186           Renvoie la date à laquelle la session expirera. Pour les sessions sans
187           date d'expiration spécifique (ou celles qui expirent à la fermeture du
188           navigateur), la valeur renvoyée sera à ``sessions.SESSION_COOKIE_AGE``
189           de l'instant présent.
190
191
192         * ``get_expire_at_browser_close()``
193
194           **Nouveau dans la version de développement de Django**
195
196           Renvoie ``True`` ou ``False``, selon que la session de l'utilisateur
197           devra expirer quand son navigateur est fermé, ou non.
198
199 Vous pouvez éditer ``request.session`` où vous le souhaitez dans vos vues. Vous
200 pouvez également l'éditer à plusieurs reprises.
201
202 Comment utiliser l'objet Session
203 --------------------------------
204
205     * Utilisez des chaînes Python classiques comme clés du dictionnaire
206       ``request.session``. Il s'agit en fait plus d'une convention que d'une
207       rÚgle absolue.
208
209     * Les clés du dictionnaire de session qui commencent par un tiret de
210       soulignement (underscore) sont réservées à Django (usage interne).
211
212     * Ne surchargez pas ``request.session`` avec un nouvel objet, et ne changez
213       pas ou n'accédez pas directement à ses attributs. Utilisez-le comme un
214       dictionnaire Python.
215
216 Exemples
217 --------
218
219 Cette vue un peu simpliste positionne la variable ``has_commented`` à ``True``
220 aprÚs qu'un utilisateur ait posté un commentaire. Elle empêche qu'un utilisateur
221 poste un commentaire plus d'une fois::
222
223     def post_comment(request, new_comment):
224         if request.session.get('has_commented', False):
225             return HttpResponse("Vous avez déjà posté un commentaire.")
226         c = comments.Comment(comment=new_comment)
227         c.save()
228         request.session['has_commented'] = True
229         return HttpResponse('Merci de votre commentaire !')
230
231 Cette vue trÚs simple authentifie un "membre" du site::
232
233     def login(request):
234         m = Member.objects.get(username=request.POST['username'])
235         if m.password == request.POST['password']:
236             request.session['member_id'] = m.id
237             return HttpResponse("Vous êtes authentifié.")
238         else:
239             return HttpResponse("Mot de passe incorrect.")
240
241 ... Et celle-ci déconnecte un membre qui s'est connecté avec la vue ``login()``
242 ci-dessus::
243
244     def logout(request):
245         try:
246             del request.session['member_id']
247         except KeyError:
248             pass
249         return HttpResponse("Vous êtes déconnecté.")
250
251 La fonction standard ``django.contrib.auth.logout()`` en fait un peu plus, pour prévenir d'éventuelles fuites de données. Elle appelle ``request.session.flush()``. Nous utilisons cet exemple comme une démonstration de l'utilisation des objets session, pas comme une implémentation complÚte de ``logout()``.
252
253 Mise en place de cookies de test
254 ================================
255
256 Django vous permet facilement de tester si le navigateur de l'utilisateur
257 accepte les cookies. Appelez simplement
258 ``request.session.set_test_cookie()`` dans une vue, puis appelez
259 ``request.session.test_cookie_worked()`` dans la vue suivante -- pas dans la
260 même vue.
261
262 Cette séparation un peu pénible entre ``set_test_cookie()`` et
263 ``test_cookie_worked`` est nécessaire à cause du mode de fonctionnement des
264 cookies. Quand vous positionnez un cookie, vous ne pouvez pas savoir si le
265 navigateur l'a accepté avant la requête suivante.
266
267 Il est recommandé d'utiliser ``delete_test_cookie()`` pour supprimer le cookie
268 de test aprÚs l'avoir utilisé. Faites-le aprÚs avoir vérifié que ce cookie a été
269 accepté.
270
271 Voici un exemple classique d'utilisation::
272
273     def login(request):
274         if request.method == 'POST':
275             if request.session.test_cookie_worked():
276                 request.session.delete_test_cookie()
277                 return HttpResponse("Vous êtes connecté.")
278             else:
279                 return HttpResponse("Activez le support des cookies dans votre navigateur et faites un nouvel essai .")
280         request.session.set_test_cookie()
281         return render_to_response('foo/login_form.html')
282
283 Utilisation des sessions en dehors des vues
284 ===========================================
285
286 **Nouveau dans la version de développement de Django**
287
288 Une API est disponible pour manipuler les données de session en dehors des
289 vues::
290
291     >>> from django.contrib.sessions.backends.db import SessionStore
292     >>> s = SessionStore(session_key='2b1189a188b44ad18c35e113ac6ceead')
293     >>> s['last_login'] = datetime.datetime(2005, 8, 20, 13, 35, 10)
294     >>> s['last_login']                     
295     datetime.datetime(2005, 8, 20, 13, 35, 0)
296     >>> s.save()
297
298 Si vous utilisez le backend ``django.contrib.sessions.backends.db``,
299 chaque session est simplement un modÚle Django. L'objet ``Session``
300 est défini dans ``django/contrib/sessions/models.py``. Parce qu'il s'agit d'un
301 modÚle comme les autres, vous pouvez accéder aux sessions en utilisant l'API de
302 base de données de Django habituelle::
303
304     >>> from django.contrib.sessions.models import Session
305     >>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
306     >>> s.expire_date
307     datetime.datetime(2005, 8, 20, 13, 35, 12)
308
309 Notez que vous devrez utiliser la fonction ``get_decoded()`` pour obtenir le
310 dictionnaire de session. C'est nécessaire parce que le dictionnaire est stocké
311 dans un format encodé particulier::
312
313     >>> s.session_data
314     'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
315     >>> s.get_decoded()
316     {'user_id': 42}
317
318 Quand les sessions sont-elles sauvegardées ?
319 ==============================================
320
321 Par défaut, Django ne sauvegarde les données de la session que quand la session
322 est modifiée -- c'est-à-dire si l'une des valeurs du dictionnaire est créée,
323 modifiée ou supprimée::
324
325     # La session est modifiée.
326     request.session['foo'] = 'bar'
327
328     # La session est modifiée.
329     del request.session['foo']
330
331     # La session est modifiée.
332     request.session['foo'] = {}
333
334     # Attention : la session N'EST PAS modifiée, parce qu'on modifie
335     # request.session['foo'] et non request.session.
336     request.session['foo']['bar'] = 'baz'
337
338 Dans le dernier cas de l'exemple ci-dessus, on peut indiquer explicitement à
339 l'objet session qu'il a été modifié en positionnant l'attribut ``modified`` sur
340 celui-ci::
341
342     request.session.modified = True
343
344 Pour modifier ce comportement par défaut, positionnez la variable
345 ``SESSION_SAVE_EVERY_REQUEST`` à ``True``. Si c'est le cas, Django sauvegardera
346 la session dans la base de données à chaque requête.
347
348 Notez que le cookie de session n'est envoyé que lorsque la session est créée ou
349 modifiée. Si ``SESSION_SAVE_EVERY_REQUEST`` vaut ``True``, le cookie de session
350 sera envoyé à chaque requête.
351
352 De la même façon, la partie expiration (``expires``) d'un cookie est mise à jour
353 à chaque fois que le cookie de session est envoyé.
354
355 Sessions temporaires ou sessions persistantes
356 =============================================
357
358 Vous pouvez contrÎler si le systÚme de sessions utilise des sessions temporaires
359 (qui ne durent que le temps de la navigation de l'utilisateur sur le site) ou
360 des sessions persistantes avec la variable ``SESSION_EXPIRE_AT_BROWSER_CLOSE``.
361
362 Par défaut, la variable ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` vaut ``False``, ce
363 qui signifie que les cookies de sessions seront stockés par les navigateurs des
364 utilisateurs pour une durée égale à ``SESSION_COOKIE_AGE``. Utilisez ces
365 réglages si vous voulez éviter à vos utilisateurs de s'authentifier à chaque
366 fois qu'ils démarrent leur navigateur.
367
368 Si ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` est positionné sur ``True``, Django
369 utilisera des cookies temporaires, qui expirent lorsque l'utilisateur ferme son
370 navigateur. Utilisez ce réglage si vous voulez forcer vos utilisateurs à
371 s'authentifier à chaque fois qu'ils ouvrent leur navigateur.
372
373 **Nouveau dans la version de développement de Django**
374
375 Ce rÚglage est une valeur par défaut globale, et peut être surchargée session
376 par session en utilisant explicitement ``request.session.set_expiry()`` comme
377 décrit ci-dessus dans `Utiliser les sessions dans les vues`_.
378
379 Purger la table des sessions
380 ============================
381
382 Notez que les données de sessions peuvent s'accumuler dans la table
383 ``django_session`` dans la base de données, et Django ne fournit *pas* de
384 systÚme de purge automatique. Il est donc de votre responsabilité de purger
385 réguliÚrement les sessions expirées.
386
387 Pour comprendre ce problÚme, considérez ce qui se passe quand un utilisateur
388 utilise une session. Quand il s'authentifie, Django ajoute une ligne à la table
389 ``django_session`` dans la base de données. Django met à jour cette ligne
390 chaque fois que les données de session changent. Si l'utilisateur se déconnecte
391 volontairement, Django détruit la ligne. Mais si l'utilisateur ne se déconnecte
392 *pas*, la ligne n'est jamais détruite.
393
394 Django fournit un exemple de script de nettoyage dans
395 ``django-admin.py cleanup``. Ce script détruit toutes les sessions de la
396 table dont la date d'expiration (``expire_date``) est dans le passé -- mais
397 votre application peut avoir des besoins différents.
398
399 RÚglages
400 ===========
401
402 Quelques `rÚglages de Django`_ vous permettent de contrÎler vos sessions :
403
404 SESSION_ENGINE
405 --------------
406
407 **Nouveau dans la version de développement de Django**
408
409 Valeur par défaut : ``django.contrib.sessions.backends.db``
410
411 ContrÎle où Django stocke les données de session. Les valeurs possibles sont :
412
413     * ``'django.contrib.sessions.backends.db'``
414     * ``'django.contrib.sessions.backends.file'``
415     * ``'django.contrib.sessions.backends.cache'``
416
417 Voir `configuration du moteur de sessions`_ pour plus de détails.
418
419 SESSION_FILE_PATH
420 -----------------
421
422 **Nouveau dans la version de développement de Django**
423
424 Valeur par défaut : ``/tmp/``
425
426 Si vous utilisez le stockage de données de session dans le systÚme de fichiers,
427 ceci indique le répertoire dans lequel Django stockera les données de session.
428
429 SESSION_COOKIE_AGE
430 ------------------
431
432 Valeur par défaut : ``1209600`` (2 semaines, en secondes)
433
434 L'âge maximum du cookie de session, en secondes.
435
436 SESSION_COOKIE_DOMAIN
437 ---------------------
438
439 Valeur par défaut : ``None``
440
441 Le nom de domaine à utiliser pour les cookies de session. Utilisez une chaîne
442 comme ``".lawrence.com"`` pour les cookies qui doivent couvrir plusieurs
443 sous-domaines, ou laissez ``None`` pour les cookies de domaines standards.
444
445 SESSION_COOKIE_NAME
446 -------------------
447
448 Valeur par défaut : ``'sessionid'``
449
450 Le nom du cookie à utiliser pour les sessions. Peut être ce que vous voulez.
451
452 SESSION_COOKIE_SECURE
453 ---------------------
454
455 Valeur par défaut : ``False``
456
457 Pour déterminer s'il faut utiliser un cookie sécurisé pour la session. Si la
458 valeur est ``True``, le cookie sera marqué comme "sécurisé", ce qui signifie que
459 le navigateur peut vérifier que le cookie n'est envoyé qu'au travers d'une
460 connexion sécurisée HTTPS.
461
462 SESSION_EXPIRE_AT_BROWSER_CLOSE
463 -------------------------------
464
465 Valeur par défaut : ``False``
466
467 Pour déterminer si la session doit expirer lorsque l'utilisateur ferme son
468 navigateur. Voir "Sessions temporaires ou sessions persistantes" ci-dessus.
469
470 SESSION_SAVE_EVERY_REQUEST
471 --------------------------
472
473 Valeur par défaut : ``False``
474
475 Pour déterminer s'il faut sauvegarder les données de session à chaque requête.
476 Si la valeur est ``False`` (valeur par défaut), les données de session ne seront
477 sauvegardées que lorsqu'elles sont modifiées -- c'est-à-dire si une quelconque
478 donnée du dictionnaire est créée, modifiée ou effacée.
479
480 .. _rÚglages de Django: ../settings/
481
482 Détails techniques
483 =====================
484
485     * Le dictionnaire de sessions devrait accepter tout objet sérialisable de
486       Python. Voir `le module pickle`_ pour plus de détails.
487
488     * Les données de session sont stockées dans la table de la base de données
489       appelée ``django_session``.
490
491     * Django n'envoie un cookie que s'il en a besoin. Si vous ne créez aucune
492       donnée de session, aucun cookie ne sera envoyé. 
493
494 .. _`le module pickle`: http://www.python.org/doc/current/lib/module-pickle.html
495
496 ID de session dans les URL
497 ==========================
498
499 Le systÚme de sessions de Django est entiÚrement et exclusivement basé sur les
500 cookies. Il ne placera pas les ID de session dans les URL en dernier ressort,
501 comme le fait PHP. C'est une décision intentionnelle. En effet, la technique des
502 ID de session dans les URL n'a pas seulement pour effet de rendre celles-ci
503 affreuses, elle rend également votre site vulnérable au vol d'ID de session via
504 l'entête "Referer".
Note: See TracBrowser for help on using the browser.