| 1 |
======================================== |
|---|
| 2 |
Authentification des utilisateurs Django |
|---|
| 3 |
======================================== |
|---|
| 4 |
|
|---|
| 5 |
Django possÚde un systÚme d'authentification des utilisateurs. Il permet de |
|---|
| 6 |
gérer des comptes utilisateurs, des groupes, des permissions et des sessions |
|---|
| 7 |
basées sur les cookies. Ce document explique son fonctionnement. |
|---|
| 8 |
|
|---|
| 9 |
Vue d'ensemble |
|---|
| 10 |
============== |
|---|
| 11 |
|
|---|
| 12 |
Le systÚme d'authentification consiste en : |
|---|
| 13 |
|
|---|
| 14 |
* Utilisateurs |
|---|
| 15 |
* Permissions : drapeaux booléens (yes/no) indiquant si un utilisateur peut |
|---|
| 16 |
ou non réaliser une certaine tâche |
|---|
| 17 |
* Groupes : une façon générique d'appliquer des étiquettes et des permissions |
|---|
| 18 |
à plus d'un utilisateur |
|---|
| 19 |
* Messages : une façon simple d'envoyer des messages à certains |
|---|
| 20 |
utilisateurs. |
|---|
| 21 |
|
|---|
| 22 |
Installation |
|---|
| 23 |
============ |
|---|
| 24 |
|
|---|
| 25 |
Le support d'authentification est inclus en tant qu'application Django dans |
|---|
| 26 |
``django.contrib.auth``. Pour l'installer, suivez ces instructions : |
|---|
| 27 |
|
|---|
| 28 |
1. Ajoutez ``django.contrib.auth`` Ã la variable ``INSTALLED_APPS`` |
|---|
| 29 |
2. Lancez la commande ``manage.py syncdb``. |
|---|
| 30 |
|
|---|
| 31 |
Notez que dans le fichier ``settings.py`` créé par défaut par ``django-admin.py |
|---|
| 32 |
startproject``, la variable ``INSTALLED_APPS`` contient déjà |
|---|
| 33 |
``django.contrib.auth`` pour vous faciliter la vie. Si c'est le cas pour vous, |
|---|
| 34 |
relancez la commande ``manage.py sycndb`` sans hésiter ; en fait, vous pouvez la |
|---|
| 35 |
lancer aussi souvent que vous le souhaitez, elle n'installera à chaque fois que |
|---|
| 36 |
ce qui est nécessaire. |
|---|
| 37 |
|
|---|
| 38 |
La commande ``syncdb`` crée les tables nécessaires dans la base de données, crée |
|---|
| 39 |
les objets permission pour toutes les applications installées qui en ont besoin, |
|---|
| 40 |
et vous demande de créer un compte superutilisateur la premiÚre fois que vous la |
|---|
| 41 |
lancez. |
|---|
| 42 |
|
|---|
| 43 |
Une fois que vous avez fait tout ça, c'est prêt. |
|---|
| 44 |
|
|---|
| 45 |
Utilisateurs |
|---|
| 46 |
============ |
|---|
| 47 |
|
|---|
| 48 |
Les utilisateurs sont représentés par un modÚle Django standard, qui est décrit |
|---|
| 49 |
dans `django/contrib/auth/models.py`_. |
|---|
| 50 |
|
|---|
| 51 |
.. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py |
|---|
| 52 |
|
|---|
| 53 |
Référence de l'API |
|---|
| 54 |
------------------ |
|---|
| 55 |
|
|---|
| 56 |
Champs |
|---|
| 57 |
~~~~~~ |
|---|
| 58 |
|
|---|
| 59 |
Les objets utilisateurs ``Users`` possÚdent les champs suivant : |
|---|
| 60 |
|
|---|
| 61 |
* ``username`` -- Requis. 30 caractÚres ou moins. CaractÚres alphanumériques |
|---|
| 62 |
seulement (lettres, chiffres et tiret de soulignement). |
|---|
| 63 |
* ``first_name`` -- Prénom. Optionnel. 30 caractÚres ou moins. |
|---|
| 64 |
* ``last_name`` -- Nom. Optionnel. 30 caractÚres ou moins. |
|---|
| 65 |
* ``email`` -- Optionnel. Adresse de courriel. |
|---|
| 66 |
* ``password`` -- Requis. Version chiffrée du mot de passe et métadonnées relatives à |
|---|
| 67 |
celui-ci (Django ne conserve pas de mot de passe en clair). Le mot de |
|---|
| 68 |
passe peut être d'une longueur quelconque et contenir n'importe quel |
|---|
| 69 |
caractÚre. Voir la section "Mot de passe" ci-dessous. |
|---|
| 70 |
* ``is_staff`` -- Booléen. Indique si cet utilisateur peut accéder au site |
|---|
| 71 |
d'administration. |
|---|
| 72 |
* ``is_active`` -- Booléen. Indique si ce compte utilisateur peut être |
|---|
| 73 |
utilisé pour se connecter au site. Positionnez ce drapeau à ``False`` |
|---|
| 74 |
plutÃŽt que d'effacer un compte utilisateur. |
|---|
| 75 |
* ``is_superuser`` -- Booléen. Indique que cet utilisateur possÚde toutes |
|---|
| 76 |
les permissions sans les lui assigner explicitement. |
|---|
| 77 |
* ``last_login`` -- Un champ ``datetime`` du dernier login de l'utilisateur. |
|---|
| 78 |
Positionné par défaut à la date courante. |
|---|
| 79 |
* ``date_joined`` -- Un champ ``datetime`` indiquant la date et l'heure de |
|---|
| 80 |
création de ce compte utilisateur. Positionné par défaut à la date |
|---|
| 81 |
courante lorsque le compte est créé. |
|---|
| 82 |
|
|---|
| 83 |
Méthodes |
|---|
| 84 |
~~~~~~~~ |
|---|
| 85 |
|
|---|
| 86 |
Les objets ``User`` possÚdent deux champs de relation plusieurs-à -plusieurs : |
|---|
| 87 |
``groups`` et ``user-permissions``. Ils peuvent accéder aux objets reliés de la |
|---|
| 88 |
même façon que tous les autres `modÚles Django`_:: |
|---|
| 89 |
|
|---|
| 90 |
myuser.groups = [group_list] |
|---|
| 91 |
myuser.groups.add(group, group, ...) |
|---|
| 92 |
myuser.groups.remove(group, group, ...) |
|---|
| 93 |
myuser.groups.clear() |
|---|
| 94 |
myuser.user_permissions = [permission_list] |
|---|
| 95 |
myuser.user_permissions.add(permission, permission, ...) |
|---|
| 96 |
myuser.user_permissions.remove(permission, permission, ...r) |
|---|
| 97 |
myuser.user_permissions.clear() |
|---|
| 98 |
|
|---|
| 99 |
En plus de ces méthodes automatiques, les objets ``User`` possÚdent les méthodes |
|---|
| 100 |
spécifiques suivantes : |
|---|
| 101 |
|
|---|
| 102 |
* ``is_anonymous()`` -- Renvoie toujours ``False``. C'est une maniÚre de |
|---|
| 103 |
distinguer les objets ``User`` et ``AnonymousUser``. En général, |
|---|
| 104 |
vous devriez préférer la méthode ``is_authenticated`` à celle-ci. |
|---|
| 105 |
|
|---|
| 106 |
* ``is_authenticated()`` -- Renvoie toujours ``True``. C'est une façon de |
|---|
| 107 |
savoir si un utilisateur a été authentifié. Cela n'implique aucune |
|---|
| 108 |
permission, et ne vérifie pas si l'utilisateur est actif - cela indique |
|---|
| 109 |
simplement que l'utilisateur a fourni un nom d'utilisateur et un mot de |
|---|
| 110 |
passe valides. |
|---|
| 111 |
|
|---|
| 112 |
* ``get_full_name()`` -- Renvoie le ``first_name`` et le ``last_name``, |
|---|
| 113 |
séparés par une espace. |
|---|
| 114 |
|
|---|
| 115 |
* ``set_password(raw_password)`` -- Positionne le mot de passe de |
|---|
| 116 |
l'utilisateur à la valeur (chaîne de caractÚres) indiquée, en prenant |
|---|
| 117 |
en charge de le chiffrement de celle-ci. Ne sauvegarde pas l'objet ``User``. |
|---|
| 118 |
|
|---|
| 119 |
* ``check_password(raw_password)`` -- Renvoie ``True`` si la chaîne fournie |
|---|
| 120 |
est le mot de passe de l'utilisateur (prend en charge le chiffrement pour |
|---|
| 121 |
faire la comparaison). |
|---|
| 122 |
|
|---|
| 123 |
* ``set_unusable_password()`` -- **Nouveau dans la version de développement de Django.** |
|---|
| 124 |
Indique que l'utilisateur n'a pas de mot de |
|---|
| 125 |
passe. Ce n'est pas la même chose qu'avoir une chaîne vide pour mot de |
|---|
| 126 |
passe. ``check_password()`` ne renverra jamais ``True`` pour cet |
|---|
| 127 |
utilisateur. Ne sauvegarde pas l'objet ``User``. |
|---|
| 128 |
|
|---|
| 129 |
Vous pouvez en avoir besoin si l'authentification de votre application se |
|---|
| 130 |
fait au travers d'une source externe existante telle qu'un annuaire LDAP. |
|---|
| 131 |
|
|---|
| 132 |
* ``has_usable_password()`` -- **Nouveau dans la version de développement de Django.** |
|---|
| 133 |
Renvoie ``False`` si ``set_unusable_password()`` a été appelé |
|---|
| 134 |
pour cet utilisateur. |
|---|
| 135 |
|
|---|
| 136 |
* ``get_group_permissions()`` -- Renvoie une liste des permissions que |
|---|
| 137 |
possÚde l'utilisateur au travers des groupes auxquels il appartient. |
|---|
| 138 |
|
|---|
| 139 |
* ``get_all_permissions()`` -- Renvoie une liste de toutes les permissions |
|---|
| 140 |
que possÚde l'utilisateur, permissions de groupes et permissions |
|---|
| 141 |
utilisateur. |
|---|
| 142 |
|
|---|
| 143 |
* ``has_perm(perm)`` -- Renvoie ``True`` si l'utilisateur possÚde la |
|---|
| 144 |
permission spécifiée (au format ``"package.codename"``). Si l'utilisateur |
|---|
| 145 |
est inactif, renvoie toujours ``False``. |
|---|
| 146 |
|
|---|
| 147 |
* ``has_perms(perm_list)`` -- Renvoie ``True`` si l'utilisateur possÚde toutes les |
|---|
| 148 |
permissions spécifiées (au format ``"package.codename"``). Si l'utilisateur |
|---|
| 149 |
est inactif, renvoie toujours ``False``. |
|---|
| 150 |
|
|---|
| 151 |
* ``has_module_perms(package_name)`` -- Renvoie ``True`` si l'utilisateur |
|---|
| 152 |
possÚde au moins une permission dans le paquet (l'application Django) |
|---|
| 153 |
indiqué. Si l'utilisateur est inactif, renvoie toujours ``False``. |
|---|
| 154 |
|
|---|
| 155 |
* ``get_and_delete_messages()`` -- Renvoie une liste d'objets ``Message`` en |
|---|
| 156 |
provenance de la file d'attente de l'utilisateur, et les supprime de |
|---|
| 157 |
celle-ci. |
|---|
| 158 |
|
|---|
| 159 |
* ``email_user(subject, message, from_email=None)`` -- Envoie un courriel à |
|---|
| 160 |
l'utilisateur. Si la paramÚtre ``from_email`` vaut ``None``, Django |
|---|
| 161 |
utilise la valeur de la variable `DEFAULT_FROM_EMAIL`_. |
|---|
| 162 |
|
|---|
| 163 |
* ``get_profile()`` -- Renvoie un profil spécifique au site pour cet |
|---|
| 164 |
utilisateur. LÚve l'exception |
|---|
| 165 |
``django.contrib.auth.models.SiteProfileNotAvailable`` si le site courant |
|---|
| 166 |
n'autorise pas les profils. Pour des informations sur les profils |
|---|
| 167 |
utilisateurs spécifiques aux sites, voir la section sur `Ajout |
|---|
| 168 |
d'informations supplémentaires sur les utilisateurs`_ ci-dessous. |
|---|
| 169 |
|
|---|
| 170 |
.. _modÚles Django: ../model-api/ |
|---|
| 171 |
.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email |
|---|
| 172 |
|
|---|
| 173 |
Gestionnaires |
|---|
| 174 |
~~~~~~~~~~~~~ |
|---|
| 175 |
|
|---|
| 176 |
Le modÚle ``User`` possÚde un gestionnaire spécifique qui fournit les fonctions |
|---|
| 177 |
suivantes : |
|---|
| 178 |
|
|---|
| 179 |
* ``create_user(username, email, password=None)`` -- Crée, sauvegarde et renvoie |
|---|
| 180 |
un objet ``User``. Les champs ``username``, ``email`` et ``password`` sont |
|---|
| 181 |
positionnés sur les valeurs fournies, et le drapeau ``is_active`` est |
|---|
| 182 |
positionné à ``True`` pour cet utilisateur. |
|---|
| 183 |
|
|---|
| 184 |
Si aucun mot de passe n'est fourni, ``set_unusable_password()`` sera |
|---|
| 185 |
appelé. |
|---|
| 186 |
|
|---|
| 187 |
Voir `Création d'utilisateurs`_ pour un exemple d'utilisation. |
|---|
| 188 |
|
|---|
| 189 |
* ``make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')`` |
|---|
| 190 |
Renvoie un mot de passe aléatoire de la longueur donnée à partir de la |
|---|
| 191 |
liste des caractÚres autorisés. Notez que la liste fournie par défaut ne |
|---|
| 192 |
contient de lettres ou chiffres pouvant prêter à confusion comme ``"I"``, ``"1"`` |
|---|
| 193 |
et ``"0"``. |
|---|
| 194 |
|
|---|
| 195 |
Utilisation de base |
|---|
| 196 |
------------------- |
|---|
| 197 |
|
|---|
| 198 |
Création d'utilisateurs |
|---|
| 199 |
~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 200 |
|
|---|
| 201 |
La façon la plus simple de créer des utilisateurs est d'utiliser la fonction ``create_user`` |
|---|
| 202 |
qui est fournie avec Django:: |
|---|
| 203 |
|
|---|
| 204 |
>>> from django.contrib.auth.models import User |
|---|
| 205 |
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword') |
|---|
| 206 |
|
|---|
| 207 |
# user est maintenant un objet User déjà sauvegardé |
|---|
| 208 |
# dans la base de données. Vous pouvez continuer à changer ses |
|---|
| 209 |
# attributs si vous voulez changer la valeur d'autres champs. |
|---|
| 210 |
>>> user.is_staff = True |
|---|
| 211 |
>>> user.save() |
|---|
| 212 |
|
|---|
| 213 |
Modifier un mot de passe |
|---|
| 214 |
~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 215 |
|
|---|
| 216 |
Utilisez ``set_password()`` pour changer un mot de passe:: |
|---|
| 217 |
|
|---|
| 218 |
>>> from django.contrib.auth.models import User |
|---|
| 219 |
>>> u = User.objects.get(username__exact='john') |
|---|
| 220 |
>>> u.set_password('new password') |
|---|
| 221 |
>>> u.save() |
|---|
| 222 |
|
|---|
| 223 |
Ne changez pas la valeur de l'attribut ``password`` directement à moins de |
|---|
| 224 |
savoir précisément ce que vous faites. Les détails sont expliqués dans la |
|---|
| 225 |
section suivante. |
|---|
| 226 |
|
|---|
| 227 |
Mots de passe |
|---|
| 228 |
------------- |
|---|
| 229 |
|
|---|
| 230 |
L'attribut ``password`` d'un objet ``User`` est une chaîne au format:: |
|---|
| 231 |
|
|---|
| 232 |
hashtype$salt$hash |
|---|
| 233 |
|
|---|
| 234 |
C'est-Ã -dire le type de chiffrement (hashtype), la graine (salt) et le mot de |
|---|
| 235 |
passé chiffré (hash), séparés par des dollars. |
|---|
| 236 |
|
|---|
| 237 |
Le type de chiffrement est ``sha1`` (par défaut), ``md5`` ou ``crypt`` -- |
|---|
| 238 |
l'algorithme utilisé pour faire le chiffrage à sens unique du mot de passe. La |
|---|
| 239 |
graine est une chaîne aléatoire utilisée dans la création du mot de passe |
|---|
| 240 |
chiffré. Notez que la méthode ``crypt`` n'est supportée que sur les plateformes |
|---|
| 241 |
sur lesquelles le module Python ``crypt`` est disponible, et le support de |
|---|
| 242 |
``crypt`` n'existe que dans la version de développement de Django. |
|---|
| 243 |
|
|---|
| 244 |
Exemple:: |
|---|
| 245 |
|
|---|
| 246 |
sha1$a1976$a36cc8cbf81742a8fb52e221aaeab48ed7f58ab4 |
|---|
| 247 |
|
|---|
| 248 |
Les fonctions ``User.set_password()`` et ``User.check_password()`` gÚrent la |
|---|
| 249 |
mise en place et la vérification de ces valeurs pour vous. |
|---|
| 250 |
|
|---|
| 251 |
Certaines versions antérieures de Django, comme la 0.90, utilisaient de simples |
|---|
| 252 |
chiffres MD5 sans utiliser de graine (salt). Pour assurer la compatibilité |
|---|
| 253 |
ascendante, ils sont toujours supportés mais seront automatiquement convertis |
|---|
| 254 |
en chiffres utilisant la nouvelle méthode la premiÚre fois que |
|---|
| 255 |
``User.check_password()`` fonctionnera correctement pour un utilisateur donné. |
|---|
| 256 |
|
|---|
| 257 |
Utilisateurs anonymes |
|---|
| 258 |
--------------------- |
|---|
| 259 |
|
|---|
| 260 |
La classe ``django.contrib.auth.models.AnonymousUser`` implémente l'interface |
|---|
| 261 |
``django.contrib.auth.models.User``, mais avec ces différences : |
|---|
| 262 |
|
|---|
| 263 |
* ``id`` vaut toujours ``None``. |
|---|
| 264 |
* ``is_staff`` et ``is_superuser`` sont toujours ``False``. |
|---|
| 265 |
* ``is_active`` est toujours ``False``. |
|---|
| 266 |
* ``groups`` et ``user_permissions`` sont toujours vides. |
|---|
| 267 |
* ``is_anonymous()`` renvoie ``True`` au lieu de ``False``. |
|---|
| 268 |
* ``is_authenticated()`` renvoie ``False`` au lieu de ``True``. |
|---|
| 269 |
* ``has_perm()`` renvoie toujours ``False``. |
|---|
| 270 |
* ``set_password()``, ``check_password()``, ``save()``, ``delete()``, |
|---|
| 271 |
``set_groups()`` et ``set_permissions()`` lÚvent l'exception ``NotImplementedError``. |
|---|
| 272 |
|
|---|
| 273 |
En pratique, vous n'aurez probablement pas à utiliser les objets |
|---|
| 274 |
``AnonymousUser`` directement, mais ils sont utilisés par les requêtes web, |
|---|
| 275 |
comme il est expliqué dans la section suivante. |
|---|
| 276 |
|
|---|
| 277 |
Création de superutilisateurs |
|---|
| 278 |
----------------------------- |
|---|
| 279 |
|
|---|
| 280 |
``manage.py syncdb`` vous propose de créer un superutilisateur la premiÚre fois |
|---|
| 281 |
que vous l'utilisez aprÚs avoir ajouté ``'django.contrib.auth'`` à vos |
|---|
| 282 |
``INSTALLED_APPS``. Mais si vous avez besoin de créer un superutilisateur aprÚs |
|---|
| 283 |
cela, vous pouvez utiliser un utilitaire en ligne de commande. |
|---|
| 284 |
|
|---|
| 285 |
**Nouveau dans la version de développement de Django**:: |
|---|
| 286 |
|
|---|
| 287 |
manage.py createsuperuser --username=joe --email=joe@example.com |
|---|
| 288 |
|
|---|
| 289 |
Il vous sera demandé un mot de passe. AprÚs que vous en ayez fourni un, |
|---|
| 290 |
l'utilisateur sera créé immédiatement. Si vous n'utilisez pas les options |
|---|
| 291 |
``--username`` et ``--email``, ces valeurs vous seront demandées. |
|---|
| 292 |
|
|---|
| 293 |
Si vous utilisez toujours une version plus ancienne de Django, la façon |
|---|
| 294 |
traditionnelle de créer un superutilisateur en ligne de commande fonctionne |
|---|
| 295 |
toujours:: |
|---|
| 296 |
|
|---|
| 297 |
python /path/to/django/contrib/auth/create_superuser.py |
|---|
| 298 |
|
|---|
| 299 |
...où ``/path/to`` est le chemin de la base de code de Django sur votre systÚme |
|---|
| 300 |
de fichiers. La commande ``manage.py`` est préférable parce qu'elle détermine |
|---|
| 301 |
les chemins et l'environnement corrects pour vous. |
|---|
| 302 |
|
|---|
| 303 |
Ajout d'informations supplémentaires sur les utilisateurs |
|---|
| 304 |
--------------------------------------------------------- |
|---|
| 305 |
|
|---|
| 306 |
Si vous souhaitez stocker des informations supplémentaires a propos de vos |
|---|
| 307 |
utilisateurs, Django fournit une technique pour spécifier un modÚle propre à votre |
|---|
| 308 |
site, en relation avec le modÚle `User`, à cet effet. Ces modÚles sont appelés |
|---|
| 309 |
"profils utilisateurs". |
|---|
| 310 |
|
|---|
| 311 |
Pour utiliser cette fonctionnalité, définissez un modÚle contenant les champs |
|---|
| 312 |
nécessaires pour les informations supplémentaires que vous souhaitez conserver, |
|---|
| 313 |
ainsi que les méthodes additionnelles dont vous voulez disposer. Ajoutez |
|---|
| 314 |
également une ``ForeignKey`` de votre modÚle vers le modÚle ``User``, en |
|---|
| 315 |
spécifiant ``unique=True`` pour être certain qu'il n'y aura qu'une seule |
|---|
| 316 |
instance de votre modÚle pour chaque ``User``. |
|---|
| 317 |
|
|---|
| 318 |
Pour indiquer que ce modÚle est le profil utilisateur pour un site donné, |
|---|
| 319 |
renseignez la variable de réglage ``AUTH_PROFILE_MODULE`` avec une chaîne formée |
|---|
| 320 |
des éléments suivant, séparés par des points : |
|---|
| 321 |
|
|---|
| 322 |
1. Le nom de l'application (en minuscules) dans laquelle le modÚle de profil |
|---|
| 323 |
utilisateur est défini (en d'autres termes, une version tout en minuscule du |
|---|
| 324 |
nom qui a été passé à ``manage.py startapp`` pour créer l'application). |
|---|
| 325 |
|
|---|
| 326 |
2. Le nom de la classe du modÚle, en minuscules également. |
|---|
| 327 |
|
|---|
| 328 |
Par exemple, si le modÚle de profil est une classe appelée ``UserProfile`` et |
|---|
| 329 |
est défini dans une application appelée ``comptes``, la variable appropriée dans |
|---|
| 330 |
votre fichier de réglages serait:: |
|---|
| 331 |
|
|---|
| 332 |
AUTH_PROFILE_MODULE = 'comptes.userprofile' |
|---|
| 333 |
|
|---|
| 334 |
Quand un profil utilisateur a été défini et spécifié de cette façon, chaque |
|---|
| 335 |
objet ``User`` aura une méthode -- ``get_profile()`` -- qui renverra l'instance du |
|---|
| 336 |
modÚle de profil utilisateur associée à ce ``User``. |
|---|
| 337 |
|
|---|
| 338 |
Pour plus d'informations, voir le `chapitre 12 du livre de Django`_. |
|---|
| 339 |
|
|---|
| 340 |
.. _chapitre 12 du livre de Django: http://www.djangobook.com/en/1.0/chapter12/#cn226 |
|---|
| 341 |
|
|---|
| 342 |
Authentification au travers des requêtes web |
|---|
| 343 |
============================================ |
|---|
| 344 |
|
|---|
| 345 |
Jusqu'à maintenant, ce document a présenté l'API de bas niveau destinée à |
|---|
| 346 |
manipuler les objets relatifs à l'authentification. A un niveau plus élevé, |
|---|
| 347 |
Django permet d'utiliser ce systÚme d'authentification au travers des `objets |
|---|
| 348 |
requêtes`_. |
|---|
| 349 |
|
|---|
| 350 |
Avant tout, installez les modules intermédiaires ``SessionMiddleware`` et |
|---|
| 351 |
``AuthenticationMiddleware`` en les ajoutant dans la variable |
|---|
| 352 |
``MIDDLEWARE_CLASSES``. Voir la `documentation des sessions`_ pour plus de |
|---|
| 353 |
détails sur ce point. |
|---|
| 354 |
|
|---|
| 355 |
Une fois que ces modules intermédiaires sont installés, vous pouvez accéder à |
|---|
| 356 |
``request.user`` dans les vues. ``request.user`` vous fournit un objet ``User`` |
|---|
| 357 |
représentant l'utilisateur actuellement authentifié. Si aucun utilisateur n'est |
|---|
| 358 |
actuellement authentifié, ``request.user`` renvoie une instance de |
|---|
| 359 |
``AnonymousUser`` (voir la section précédente). Vous pouvez distinguer |
|---|
| 360 |
l'utilisateur authentifié d'un utilisateur anonyme à l'aide de |
|---|
| 361 |
``is_authenticated()`` de cette façon :: |
|---|
| 362 |
|
|---|
| 363 |
if request.user.is_authenticated(): |
|---|
| 364 |
# Traitement d'un utilisateur authentifié. |
|---|
| 365 |
else: |
|---|
| 366 |
# Traitement d'un utilisateur anonyme. |
|---|
| 367 |
|
|---|
| 368 |
.. _objets requêtes: ../request_response/#httprequest-objects |
|---|
| 369 |
.. _documentation des sessions: ../sessions/ |
|---|
| 370 |
|
|---|
| 371 |
Comment authentifier un utilisateur |
|---|
| 372 |
----------------------------------- |
|---|
| 373 |
|
|---|
| 374 |
Django fournit deux fonctions dans ``django.contrib.auth`` : ``authenticate()`` |
|---|
| 375 |
et ``login()``. |
|---|
| 376 |
|
|---|
| 377 |
Pour authentifier un couple utilisateur-mot de passe donné, utilisez |
|---|
| 378 |
``authenticate()``. La fonction prend deux arguments, ``username`` et |
|---|
| 379 |
``password``, et renvoie un objet ``User`` si le mot de passe est valide pour |
|---|
| 380 |
l'utilisateur donné. Si le mot de passe est invalide, ``authenticate()`` renvoie |
|---|
| 381 |
``None``. Exemple:: |
|---|
| 382 |
|
|---|
| 383 |
from django.contrib.auth import authenticate |
|---|
| 384 |
user = authenticate(username='john', password='secret') |
|---|
| 385 |
if user is not None: |
|---|
| 386 |
if user.is_active: |
|---|
| 387 |
print "You provided a correct username and password!" |
|---|
| 388 |
else: |
|---|
| 389 |
print "Your account has been disabled!" |
|---|
| 390 |
else: |
|---|
| 391 |
print "Your username and password were incorrect." |
|---|
| 392 |
|
|---|
| 393 |
Pour authentifier un utilisateur dans une vue, utilisez ``login()``. Cette |
|---|
| 394 |
fonction prend un objet ``HttpRequest`` et un objet ``User``. ``login()`` sauve |
|---|
| 395 |
l'ID de l'utilisateur dans la session courante en utilisant la gestion des |
|---|
| 396 |
sessions de Django, donc, il faut que le module intermédiaire de gestion des |
|---|
| 397 |
sessions soit installé comme indiqué ci-dessus. |
|---|
| 398 |
|
|---|
| 399 |
Cet exemple montre comment utiliser ``authenticate()`` et ``login()`` pour |
|---|
| 400 |
authentifier un utilisateur:: |
|---|
| 401 |
|
|---|
| 402 |
from django.contrib.auth import authenticate, login |
|---|
| 403 |
|
|---|
| 404 |
def my_view(request): |
|---|
| 405 |
username = request.POST['username'] |
|---|
| 406 |
password = request.POST['password'] |
|---|
| 407 |
user = authenticate(username=username, password=password) |
|---|
| 408 |
if user is not None: |
|---|
| 409 |
if user.is_active: |
|---|
| 410 |
login(request, user) |
|---|
| 411 |
# Redirection vers une page de succÚs. |
|---|
| 412 |
else: |
|---|
| 413 |
# Renvoyer un message d'erreur 'compte inactif'. |
|---|
| 414 |
else: |
|---|
| 415 |
# Renvoyer un message d'erreur 'login invalide'. |
|---|
| 416 |
|
|---|
| 417 |
.. admonition:: Appeler d'abord ``authenticate()`` |
|---|
| 418 |
|
|---|
| 419 |
Quand vous authentifiez manuellement un utilisateur, vous *devez* appeler |
|---|
| 420 |
``authenticate()`` avant d'appeler ``login()``. ``authenticate()`` place un |
|---|
| 421 |
attribut sur le ``User``, indiquant quel backend a pu authentifier cet |
|---|
| 422 |
utilisateur (voir la `documentation des backends`_ pour des détails), et |
|---|
| 423 |
cette information est nécessaire plus tard dans le processus de login. |
|---|
| 424 |
|
|---|
| 425 |
.. _documentation des backends: #other-authentication-sources |
|---|
| 426 |
|
|---|
| 427 |
Vérification manuelle du mot de passe d'un utilisateur |
|---|
| 428 |
------------------------------------------------------ |
|---|
| 429 |
|
|---|
| 430 |
Si vous souhaitez authentifier manuellement un utilisateur en comparant un mot |
|---|
| 431 |
de passe clair à la version chiffrée stockée dans la base de données, utilisez |
|---|
| 432 |
la fonction ``django.contrib.auth.models.check_password``. Elle prend deux |
|---|
| 433 |
arguments : le mot de passe en clair à vérifier, et la valeur du champ |
|---|
| 434 |
``password`` de l'utilisateur concerné dans la base de données, et renvoie ``True`` |
|---|
| 435 |
s'ils correspondent, ``False`` sinon. |
|---|
| 436 |
|
|---|
| 437 |
Comment déconnecter un utilisateur |
|---|
| 438 |
---------------------------------- |
|---|
| 439 |
|
|---|
| 440 |
Pour déconnecter un utilisateur qui a été authentifié via |
|---|
| 441 |
``django.contrib.auth.login()``, utilisez ``django.contrib.auth.logout()`` dans |
|---|
| 442 |
votre vue. Cette fonction prend un objet ``HttpRequest`` et n'a pas de valeur de |
|---|
| 443 |
retour. Exemple:: |
|---|
| 444 |
|
|---|
| 445 |
from django.contrib.auth import logout |
|---|
| 446 |
|
|---|
| 447 |
def logout_view(request): |
|---|
| 448 |
logout(request) |
|---|
| 449 |
# Redirection vers une autre page. |
|---|
| 450 |
|
|---|
| 451 |
Notez que ``logout()`` ne renvoie aucune erreur si l'utilisateur n'était pas |
|---|
| 452 |
authentifié. |
|---|
| 453 |
|
|---|
| 454 |
**Nouveau dans la version de développement de Django** : Quand vous appellez |
|---|
| 455 |
``logout()``, les données de sessions de la requête courante sont complÚtement |
|---|
| 456 |
effacées. C'est pour empêcher une autre personne d'utiliser le même navigateur |
|---|
| 457 |
web pour se connecter et avoir accÚs aux données de la session de l'utilisateur |
|---|
| 458 |
précédent. Si vous voulez placer dans la session une information qui doit rester |
|---|
| 459 |
disponible aprÚs la déconnexion, faites-le *aprÚs* avoir appelé |
|---|
| 460 |
``django.contrib.auth.logout()``. |
|---|
| 461 |
|
|---|
| 462 |
Limiter l'accÚs aux utilisateurs authentifiés |
|---|
| 463 |
--------------------------------------------- |
|---|
| 464 |
|
|---|
| 465 |
La maniÚre de base |
|---|
| 466 |
~~~~~~~~~~~~~~~~~~ |
|---|
| 467 |
|
|---|
| 468 |
La façon simple et basique de limiter l'accÚs à une page est de vérifier la |
|---|
| 469 |
valeur de ``request.user.is_authenticated()`` et de rediriger vers une page |
|---|
| 470 |
d'accÚs (login):: |
|---|
| 471 |
|
|---|
| 472 |
from django.http import HttpResponseRedirect |
|---|
| 473 |
|
|---|
| 474 |
def my_view(request): |
|---|
| 475 |
if not request.user.is_authenticated(): |
|---|
| 476 |
return HttpResponseRedirect('/login/?next=%s' % request.path) |
|---|
| 477 |
# ... |
|---|
| 478 |
|
|---|
| 479 |
...ou d'envoyer un message d'erreur:: |
|---|
| 480 |
|
|---|
| 481 |
def my_view(request): |
|---|
| 482 |
if not request.user.is_authenticated(): |
|---|
| 483 |
return render_to_response('myapp/login_error.html') |
|---|
| 484 |
# ... |
|---|
| 485 |
|
|---|
| 486 |
Le decorator login_required |
|---|
| 487 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 488 |
|
|---|
| 489 |
Toutefois, vous pouvez vous simplifier le travail en utilisant le decorator |
|---|
| 490 |
``login_required``:: |
|---|
| 491 |
|
|---|
| 492 |
from django.contrib.auth.decorators import login_required |
|---|
| 493 |
|
|---|
| 494 |
def my_view(request): |
|---|
| 495 |
# ... |
|---|
| 496 |
my_view = login_required(my_view) |
|---|
| 497 |
|
|---|
| 498 |
Un exemple équivalent, en utilisant la syntaxe plus concise introduite dans |
|---|
| 499 |
Python 2.4:: |
|---|
| 500 |
|
|---|
| 501 |
from django.contrib.auth.decorators import login_required |
|---|
| 502 |
|
|---|
| 503 |
@login_required |
|---|
| 504 |
def my_view(request): |
|---|
| 505 |
# ... |
|---|
| 506 |
|
|---|
| 507 |
Dans la version de développement de Django, ``login_required`` a aussi un |
|---|
| 508 |
paramÚtre optionnel ``redirect_field_name``. Exemple:: |
|---|
| 509 |
|
|---|
| 510 |
from django.contrib.auth.decorators import login_required |
|---|
| 511 |
|
|---|
| 512 |
def my_view(request): |
|---|
| 513 |
# ... |
|---|
| 514 |
my_view = login_required(redirect_field_name='redirect_to')(my_view) |
|---|
| 515 |
|
|---|
| 516 |
Toujours un exemple équivalent avec la syntaxe plus concise introduite dans |
|---|
| 517 |
Python 2.4:: |
|---|
| 518 |
|
|---|
| 519 |
from django.contrib.auth.decorators import login_required |
|---|
| 520 |
|
|---|
| 521 |
@login_required(redirect_field_name='redirect_to') |
|---|
| 522 |
def my_view(request): |
|---|
| 523 |
# ... |
|---|
| 524 |
|
|---|
| 525 |
|
|---|
| 526 |
``login_required`` fait pour vous les choses suivantes : |
|---|
| 527 |
|
|---|
| 528 |
* Si l'utilisateur n'est pas authentifié, redirection vers la page |
|---|
| 529 |
``settings.LOGIN_URL`` (``accounts/login`` par défaut), en lui passant |
|---|
| 530 |
l'URL absolue de la page courante dans la requête comme paramÚtre pour |
|---|
| 531 |
``next`` (ou la valeur de ``redirect_field_name``). Par exemple : |
|---|
| 532 |
``/accounts/login/?next=/polls/3/``. |
|---|
| 533 |
|
|---|
| 534 |
* Si l'utilisateur est authentifié, exécute la vue normalement. Le code de |
|---|
| 535 |
la vue peut considérer que l'utilisateur s'est authentifié correctement. |
|---|
| 536 |
|
|---|
| 537 |
Notez que vous devrez associer la bonne vue à ``settings.LOGIN_URL``. Par |
|---|
| 538 |
exemple, pour utiliser les valeurs par défaut, ajoutez la ligne suivante a votre |
|---|
| 539 |
URLconf:: |
|---|
| 540 |
|
|---|
| 541 |
(r'^accounts/login/$', 'django.contrib.auth.views.login'), |
|---|
| 542 |
|
|---|
| 543 |
Voici ce que fait ``django.contrib.auth.views.login`` : |
|---|
| 544 |
|
|---|
| 545 |
* Si la vue est appelée par ``GET``, elle affiche un formulaire d'authentification |
|---|
| 546 |
qui enverra les informations par ``POST`` sur la même URL. Voir |
|---|
| 547 |
ci-dessous. |
|---|
| 548 |
|
|---|
| 549 |
* Si la vue est appelée par ``POST``, elle essaie d'authentifier l'utilisateur. En |
|---|
| 550 |
cas de succÚs, elle redirige vers l'URL spécifiée dans ``next``. Si aucune |
|---|
| 551 |
valeur n'est fournie pour ``next``, elle redirige vers |
|---|
| 552 |
``settings.LOGIN_REDIRECT_URL`` (qui par défaut est |
|---|
| 553 |
``/accounts/profile/``). Si l'authentification est un échec, elle |
|---|
| 554 |
ré-affiche le formulaire d'authentification. |
|---|
| 555 |
|
|---|
| 556 |
Il est de votre responsabilité de fournir le formulaire d'authentification dans |
|---|
| 557 |
un template appelé ``registration/login.html`` par défaut. Trois variables de |
|---|
| 558 |
contexte sont passées à ce template : |
|---|
| 559 |
|
|---|
| 560 |
* ``form`` : Un objet ``Form`` représentant le formulaire |
|---|
| 561 |
d'authentification. Voir la `documentation des formulaires`_ pour en savoir |
|---|
| 562 |
plus sur les objets ``FormWrapper``. |
|---|
| 563 |
* ``next`` : L'URL vers laquelle rediriger si l'authentification est un |
|---|
| 564 |
succÚs. Peut également contenir une chaîne de requête. |
|---|
| 565 |
* ``site_name`` : Le nom du ``Site`` courant, tel que fourni par la variable |
|---|
| 566 |
``SITE_ID``. Si vous utilisez la version de développement de Django et que |
|---|
| 567 |
vous n'avez pas installé le systÚme de gestion de sites, la valeur sera |
|---|
| 568 |
celle de ``request.META['SERVER_NAME']``. Pour plus d'informations sur le |
|---|
| 569 |
systÚme de gestion de sites, voir la `documentation sites`_. |
|---|
| 570 |
|
|---|
| 571 |
Si vous préférez appeler le template autrement que ``registration/login.html``, |
|---|
| 572 |
vous pouvez passer le paramÚtre ``template_name`` comme argument supplémentaire |
|---|
| 573 |
à la vue dans votre URLconf. Par exemple, cette ligne d'URLconf utiliserait |
|---|
| 574 |
``myapp/login.html`` Ã la place:: |
|---|
| 575 |
|
|---|
| 576 |
(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}), |
|---|
| 577 |
|
|---|
| 578 |
Voici un exemple de template ``registration/login.html`` que vous pouvez utiliser |
|---|
| 579 |
comme point de départ. Il suppose que vous avez un template ``base.html`` qui |
|---|
| 580 |
définit un bloc ``content`` : :: |
|---|
| 581 |
|
|---|
| 582 |
{% extends "base.html" %} |
|---|
| 583 |
|
|---|
| 584 |
{% block content %} |
|---|
| 585 |
|
|---|
| 586 |
{% if form.errors %} |
|---|
| 587 |
<p>Utilisateur et mot de passe incorrects. Essayez à nouveau s'il vous plaît.</p> |
|---|
| 588 |
{% endif %} |
|---|
| 589 |
|
|---|
| 590 |
<form method="post" action="."> |
|---|
| 591 |
<table> |
|---|
| 592 |
<tr><td>{{ form.username.label_tag }}</td><td>{{ form.username }}</td></tr> |
|---|
| 593 |
<tr><td>{{ form.password.label_tag }}</td><td>{{ form.password }}</td></tr> |
|---|
| 594 |
</table> |
|---|
| 595 |
|
|---|
| 596 |
<input type="submit" value="login" /> |
|---|
| 597 |
<input type="hidden" name="next" value="{{ next }}" /> |
|---|
| 598 |
</form> |
|---|
| 599 |
|
|---|
| 600 |
{% endblock %} |
|---|
| 601 |
|
|---|
| 602 |
.. _documentation des formulaires: ../forms/ |
|---|
| 603 |
.. _documentation sites: ../sites/ |
|---|
| 604 |
|
|---|
| 605 |
Autres vues prêtes à l'emploi |
|---|
| 606 |
----------------------------- |
|---|
| 607 |
|
|---|
| 608 |
En plus de la vue ``login``, le systÚme d'authentification contient quelques vues |
|---|
| 609 |
prêtes à l'emploi utiles : |
|---|
| 610 |
|
|---|
| 611 |
``django.contrib.auth.views.logout`` |
|---|
| 612 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 613 |
|
|---|
| 614 |
**Description :** |
|---|
| 615 |
|
|---|
| 616 |
Déconnecte un utilisateur. |
|---|
| 617 |
|
|---|
| 618 |
**ParamÚtres optionnels :** |
|---|
| 619 |
|
|---|
| 620 |
* ``template_name``: Le nom complet d'un template à afficher aprÚs que |
|---|
| 621 |
l'utilisateur se soit déconnecté. La valeur par défaut est |
|---|
| 622 |
``registration/logged_out.html`` si aucun autre argument n'est fourni. |
|---|
| 623 |
|
|---|
| 624 |
**Contexte de template :** |
|---|
| 625 |
|
|---|
| 626 |
* ``title``: La chaîne "Logged out", traduite. |
|---|
| 627 |
|
|---|
| 628 |
``django.contrib.auth.views.logout_then_login`` |
|---|
| 629 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 630 |
|
|---|
| 631 |
**Description :** |
|---|
| 632 |
|
|---|
| 633 |
Déconnecte un utilisateur, puis le redirige vers la page d'authentification. |
|---|
| 634 |
|
|---|
| 635 |
**ParamÚtres optionnels :** |
|---|
| 636 |
|
|---|
| 637 |
* ``login_url``: L'URL de la page d'authentification. La valeur par défaut |
|---|
| 638 |
est ``settings.LOGIN_URL``. |
|---|
| 639 |
|
|---|
| 640 |
``django.contrib.auth.views.password_change`` |
|---|
| 641 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 642 |
|
|---|
| 643 |
**Description :** |
|---|
| 644 |
|
|---|
| 645 |
Permet à un utilisateur de changer de mot de passe. |
|---|
| 646 |
|
|---|
| 647 |
**ParamÚtres optionnels :** |
|---|
| 648 |
|
|---|
| 649 |
* ``template_name``: Le nom complet du template à utiliser pour afficher le |
|---|
| 650 |
formulaire de changement de mot de passe. La valeur par défaut est |
|---|
| 651 |
``registration/password_change_form.html``. |
|---|
| 652 |
|
|---|
| 653 |
**Contexte de template :** |
|---|
| 654 |
|
|---|
| 655 |
* ``form``: Le formulaire de changement de mot de passe. |
|---|
| 656 |
|
|---|
| 657 |
``django.contrib.auth.views.password_change_done`` |
|---|
| 658 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 659 |
|
|---|
| 660 |
**Description :** |
|---|
| 661 |
|
|---|
| 662 |
La page affichée aprÚs qu'un utilisateur ait changé de mot de passe. |
|---|
| 663 |
|
|---|
| 664 |
**ParamÚtres optionnels :** |
|---|
| 665 |
|
|---|
| 666 |
* ``template_name``: Le nom complet du template à utiliser. La valeur par |
|---|
| 667 |
défaut est ``registration/password_change_done.html``. |
|---|
| 668 |
|
|---|
| 669 |
``django.contrib.auth.views.password_reset`` |
|---|
| 670 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 671 |
|
|---|
| 672 |
**Description :** |
|---|
| 673 |
|
|---|
| 674 |
Permet à un utilisateur de réinitialiser son mot de passe, et lui envoie le |
|---|
| 675 |
nouveau mot de passe par courriel. |
|---|
| 676 |
|
|---|
| 677 |
**ParamÚtres optionnels :** |
|---|
| 678 |
|
|---|
| 679 |
* ``template_name``: Le nom complet du template à utiliser pour afficher le |
|---|
| 680 |
formulaire de réinitialisation du mot de passe. La valeur par défaut est |
|---|
| 681 |
``registration/password_reset_form.html``. |
|---|
| 682 |
|
|---|
| 683 |
* ``email_template_name``: Le nom complet du template à utiliser pour générer |
|---|
| 684 |
le courriel avec le nouveau mot de passe. La valeur par défaut est |
|---|
| 685 |
``registration/password_reset_email.html``. |
|---|
| 686 |
|
|---|
| 687 |
**Contexte de template :** |
|---|
| 688 |
|
|---|
| 689 |
* ``form``: Le formulaire de réinitialisation du mot de passe. |
|---|
| 690 |
|
|---|
| 691 |
``django.contrib.auth.views.password_reset_done`` |
|---|
| 692 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 693 |
|
|---|
| 694 |
**Description :** |
|---|
| 695 |
|
|---|
| 696 |
La page affichée aprÚs qu'un utilisateur ait réinitialisé son mot de passe. |
|---|
| 697 |
|
|---|
| 698 |
**ParamÚtres optionnels :** |
|---|
| 699 |
|
|---|
| 700 |
* ``template_name``: Le nom complet du template à utiliser. La valeur par |
|---|
| 701 |
défaut est ``registration/password_reset_done.html``. |
|---|
| 702 |
|
|---|
| 703 |
``django.contrib.auth.views.redirect_to_login`` |
|---|
| 704 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 705 |
|
|---|
| 706 |
**Description :** |
|---|
| 707 |
|
|---|
| 708 |
Redirige vers la page d'authentification, puis vers une autre URL si |
|---|
| 709 |
l'authentification a été un succÚs. |
|---|
| 710 |
|
|---|
| 711 |
**ParamÚtre requis :** |
|---|
| 712 |
|
|---|
| 713 |
* ``next``: L'URL vers laquelle rediriger aprÚs un succÚs. |
|---|
| 714 |
|
|---|
| 715 |
**ParamÚtres optionnels :** |
|---|
| 716 |
|
|---|
| 717 |
* ``login_url``: L'URL de la page d'authentification vers laquelle |
|---|
| 718 |
rediriger. La valeur par défaut est ``settings.LOGIN_URL``. |
|---|
| 719 |
|
|---|
| 720 |
Formulaires par défaut |
|---|
| 721 |
---------------------- |
|---|
| 722 |
|
|---|
| 723 |
**Nouveau dans la version de développement de Django** |
|---|
| 724 |
|
|---|
| 725 |
Si vous ne souhaitez pas utiliser les vues prêtes à l'emploi, mais voulez |
|---|
| 726 |
conserver l'avantage de ne pas avoir à écrire de formulaires pour cette |
|---|
| 727 |
fonctionnalité, le systÚme d'authentification vous fournit plusieurs formulaires : |
|---|
| 728 |
|
|---|
| 729 |
* ``django.contrib.auth.forms.AdminPasswordChangeForm``: Un |
|---|
| 730 |
formulaire utilisé dans l'interface d'administration pour changer le mot |
|---|
| 731 |
de passe d'un utilisateur. |
|---|
| 732 |
|
|---|
| 733 |
* ``django.contrib.auth.forms.AuthenticationForm``: Un formulaire |
|---|
| 734 |
pour authentifier un utilisateur |
|---|
| 735 |
|
|---|
| 736 |
* ``django.contrib.auth.forms.PasswordChangeForm``: Un formulaire pour |
|---|
| 737 |
permettre à un utilisateur de changer de mot de passe. |
|---|
| 738 |
|
|---|
| 739 |
* ``django.contrib.auth.forms.PasswordResetForm``: Un formulaire |
|---|
| 740 |
pour réinitialiser le mot de passe d'un utilisateur et lui envoyer le |
|---|
| 741 |
nouveau mot de passe par courriel. |
|---|
| 742 |
|
|---|
| 743 |
* ``django.contrib.auth.forms.UserCreationForm``: Un formulaire |
|---|
| 744 |
pour créer un nouvel utilisateur. |
|---|
| 745 |
|
|---|
| 746 |
Limiter l'accÚs aux utilisateurs authentifiés qui satisfont une autre condition |
|---|
| 747 |
------------------------------------------------------------------------------- |
|---|
| 748 |
|
|---|
| 749 |
Pour limiter l'accÚs sur la base de certaines permissions ou d'autres |
|---|
| 750 |
conditions, le principe est le même que celui décrit dans la section précédente. |
|---|
| 751 |
|
|---|
| 752 |
La façon la plus simple est de tester votre condition sur ``request.user`` |
|---|
| 753 |
directement dans la vue. Par exemple, cette vue vérifie que l'utilisateur est |
|---|
| 754 |
authentifié et a la permission ``polls.can_vote``:: |
|---|
| 755 |
|
|---|
| 756 |
def my_view(request): |
|---|
| 757 |
if not (request.user.is_authenticated() and request.user.has_perm('polls.can_vote')): |
|---|
| 758 |
return HttpResponse("Vous ne pouvez pas voter dans ce sondage.") |
|---|
| 759 |
# ... |
|---|
| 760 |
|
|---|
| 761 |
Vous pouvez utiliser le decorator ``user_passes_test`` qui est un raccourci bien |
|---|
| 762 |
pratique:: |
|---|
| 763 |
|
|---|
| 764 |
from django.contrib.auth.decorators import user_passes_test |
|---|
| 765 |
|
|---|
| 766 |
def my_view(request): |
|---|
| 767 |
# ... |
|---|
| 768 |
my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view) |
|---|
| 769 |
|
|---|
| 770 |
On utilise ce test en particulier pour faire un exemple relativement simple. Si |
|---|
| 771 |
toutefois vous voulez simplement savoir si un utilisateur a une permission |
|---|
| 772 |
donnée, utilisez le decorator ``permission_required()`` qui est décrit plus loin |
|---|
| 773 |
dans ce document. |
|---|
| 774 |
|
|---|
| 775 |
Voici la même chose en utilisant la syntaxe de decorator de Python 2.4:: |
|---|
| 776 |
|
|---|
| 777 |
from django.contrib.auth.decorators import user_passes_test |
|---|
| 778 |
|
|---|
| 779 |
@user_passes_test(lambda u: u.has_perm('polls.can_vote')) |
|---|
| 780 |
def my_view(request): |
|---|
| 781 |
# ... |
|---|
| 782 |
|
|---|
| 783 |
``user_passes_test`` a un paramÚtre obligatoire : un objet appelable qui |
|---|
| 784 |
prend un objet ``User`` et renvoie ``True`` si l'utilisateur est autorisé à voir |
|---|
| 785 |
la page. Notez que ``user_passes_test`` ne vérifie pas automatiquement si |
|---|
| 786 |
l'utilisateur est anonyme ou non. |
|---|
| 787 |
|
|---|
| 788 |
``user_passes_test()`` a également un paramÚtre optionnel, ``login_url``, qui |
|---|
| 789 |
vous permet de préciser l'URL de votre page d'authentification |
|---|
| 790 |
(``settings.LOGIN_URL`` par défaut). |
|---|
| 791 |
|
|---|
| 792 |
Exemple avec la syntaxe de Python 2.3:: |
|---|
| 793 |
|
|---|
| 794 |
from django.contrib.auth.decorators import user_passes_test |
|---|
| 795 |
|
|---|
| 796 |
def my_view(request): |
|---|
| 797 |
# ... |
|---|
| 798 |
my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')(my_view) |
|---|
| 799 |
|
|---|
| 800 |
Exemple avec la syntaxe de Python 2.4:: |
|---|
| 801 |
|
|---|
| 802 |
from django.contrib.auth.decorators import user_passes_test |
|---|
| 803 |
|
|---|
| 804 |
@user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/') |
|---|
| 805 |
def my_view(request): |
|---|
| 806 |
# ... |
|---|
| 807 |
|
|---|
| 808 |
Le decorator permission_required |
|---|
| 809 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 810 |
|
|---|
| 811 |
Il est relativement courant de vérifier si un utilisateur possÚde une permission |
|---|
| 812 |
donnée. C'est pourquoi Django fournit un utilitaire à cet effet, le decorator |
|---|
| 813 |
``permission_required()``. En utilisant ce decorator, l'exemple de la section |
|---|
| 814 |
précédente devient:: |
|---|
| 815 |
|
|---|
| 816 |
from django.contrib.auth.decorators import permission_required |
|---|
| 817 |
|
|---|
| 818 |
def my_view(request): |
|---|
| 819 |
# ... |
|---|
| 820 |
my_view = permission_required('polls.can_vote')(my_view) |
|---|
| 821 |
|
|---|
| 822 |
Notez que ``permission_required()`` a aussi le paramÚtre optionnel |
|---|
| 823 |
``login_url``. Exemple:: |
|---|
| 824 |
|
|---|
| 825 |
from django.contrib.auth.decorators import permission_required |
|---|
| 826 |
|
|---|
| 827 |
def my_view(request): |
|---|
| 828 |
# ... |
|---|
| 829 |
my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view) |
|---|
| 830 |
|
|---|
| 831 |
Comme le decorator ``login_required``, ``login_url`` a |
|---|
| 832 |
``settings.LOGIN_URL`` pour valeur par défaut. |
|---|
| 833 |
|
|---|
| 834 |
Limiter l'accÚs aux vues génériques |
|---|
| 835 |
----------------------------------- |
|---|
| 836 |
|
|---|
| 837 |
Pour limiter l'accÚs aux `vues génériques`_, encapsulez la vue et faites pointer |
|---|
| 838 |
l'URLconf vers le code qui l'encapsule plutÎt que vers la vue elle-même. |
|---|
| 839 |
Par exemple:: |
|---|
| 840 |
|
|---|
| 841 |
from django.views.generic.date_based import object_detail |
|---|
| 842 |
|
|---|
| 843 |
@login_required |
|---|
| 844 |
def limited_object_detail(*args, **kwargs): |
|---|
| 845 |
return object_detail(*args, **kwargs) |
|---|
| 846 |
|
|---|
| 847 |
.. _vues génériques: ../generic_views/ |
|---|
| 848 |
|
|---|
| 849 |
Permissions |
|---|
| 850 |
=========== |
|---|
| 851 |
|
|---|
| 852 |
Django procure un systÚme de permissions simple. Il fournit une façon d'assigner |
|---|
| 853 |
des permissions à des utilisateurs spécifiques, ou à des groupes d'utilisateurs. |
|---|
| 854 |
|
|---|
| 855 |
Ce systÚme est utilisé par le site d'administration de Django, mais vous pouvez bien sûr |
|---|
| 856 |
l'utiliser dans votre propre code. |
|---|
| 857 |
|
|---|
| 858 |
Le site d'administration utilise les permissions de la maniÚre suivante: |
|---|
| 859 |
|
|---|
| 860 |
* L'accÚs au formulaire d'ajout et l'ajout d'un objet particulier ne sont |
|---|
| 861 |
autorisés qu'aux utilisateurs qui ont la permission "add" pour cet objet. |
|---|
| 862 |
* L'accÚs à la liste de modifications, au formulaire de modification et la |
|---|
| 863 |
modification d'un objet ne sont autorisés qu'aux utilisateurs qui ont la |
|---|
| 864 |
permission "change" pour ce type d'objet. |
|---|
| 865 |
* La possibilité d'effacer un objet n'est autorisée qu'aux utilisateurs qui |
|---|
| 866 |
ont la permission "delete" pour ce type d'objet. |
|---|
| 867 |
|
|---|
| 868 |
Les permissions sont positionnées globalement par type d'objet, par pour une |
|---|
| 869 |
instance spécifique d'un objet. Par example il est possible de dire "Marie peut |
|---|
| 870 |
modifier les nouveaux articles", mais il n'est pas possible actuellement de dire |
|---|
| 871 |
"Marie peut modifier les nouveaux articles, mais seulement ceux qu'elle a écrits |
|---|
| 872 |
elle-même", ou "Marie ne peut modifier que les articles qui ont un certain |
|---|
| 873 |
statut, date de publication ou ID". Cette derniÚre fonctionnalité est en |
|---|
| 874 |
discussion dans la communauté des développeurs Django. |
|---|
| 875 |
|
|---|
| 876 |
Permissions par défaut |
|---|
| 877 |
---------------------- |
|---|
| 878 |
|
|---|
| 879 |
Quand ``django.contrib.auth`` est listé dans votre réglage ``INSTALLED_APPS``, |
|---|
| 880 |
vous êtes sûrs que trois permissions par défaut -- "add", "change" et "delete" |
|---|
| 881 |
-- sont créées pour chaque modÚle Django défini dans vos applications |
|---|
| 882 |
installées. |
|---|
| 883 |
|
|---|
| 884 |
Ces permissions seront créées lorsque vous lancez ``manage.py syncdb`` ; la |
|---|
| 885 |
premiÚre fois que vous utilisez ``syncdb`` aprÚs avoir ajouté |
|---|
| 886 |
``django.contrib.auth`` à ``INSTALLED_APPS``, les permissions par défaut seront |
|---|
| 887 |
créées pour tous les modÚles installés précédemment, comme pour tous les |
|---|
| 888 |
nouveaux modÚles installés cette fois là . Par la suite, les permissions par |
|---|
| 889 |
défaut seront créées pour les nouveaux modÚles chaque fois que vous lancerez |
|---|
| 890 |
``manage.py syncdb``. |
|---|
| 891 |
|
|---|
| 892 |
Permissions personnalisées |
|---|
| 893 |
-------------------------- |
|---|
| 894 |
|
|---|
| 895 |
Pour créer des permissions personnalisées pour un modÚle, utilisez `l'attribut |
|---|
| 896 |
Meta des modÚles`_ ``permissions``. |
|---|
| 897 |
|
|---|
| 898 |
Ce modÚle d'exemple crée trois permissions personnalisées:: |
|---|
| 899 |
|
|---|
| 900 |
class USCitizen(models.Model): |
|---|
| 901 |
# ... |
|---|
| 902 |
class Meta: |
|---|
| 903 |
permissions = ( |
|---|
| 904 |
("can_drive", "Can drive"), |
|---|
| 905 |
("can_vote", "Can vote in elections"), |
|---|
| 906 |
("can_drink", "Can drink alcohol"), |
|---|
| 907 |
) |
|---|
| 908 |
|
|---|
| 909 |
La seule chose que cela fait en pratique est de créer ces permissions |
|---|
| 910 |
supplémentaires lorsque vous lancez ``syncdb``. |
|---|
| 911 |
|
|---|
| 912 |
.. _l'attribut Meta des modÚles: ../model-api/#meta-options |
|---|
| 913 |
|
|---|
| 914 |
Référence de l'API |
|---|
| 915 |
------------------ |
|---|
| 916 |
|
|---|
| 917 |
Comme les utilisateurs, les permissions sont implémentées dans un modÚle Django |
|---|
| 918 |
qui se trouve dans `django/contrib/auth/models.py`_. |
|---|
| 919 |
|
|---|
| 920 |
.. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py |
|---|
| 921 |
|
|---|
| 922 |
Champs |
|---|
| 923 |
~~~~~~ |
|---|
| 924 |
|
|---|
| 925 |
Les objets ``Permission`` possÚdent les champs suivants : |
|---|
| 926 |
|
|---|
| 927 |
* ``name`` -- Requis. 50 caractÚres ou moins. Exemple: ``'Peut voter'``. |
|---|
| 928 |
* ``content_type`` -- Requis. Référence à la table de base de données |
|---|
| 929 |
``django_content_type``, qui contient une ligne pour chaque modÚle Django |
|---|
| 930 |
installé. |
|---|
| 931 |
* ``codename`` -- Requis. 100 caractÚres ou moins. Exemple: ``'peut_voter'``. |
|---|
| 932 |
|
|---|
| 933 |
Méthodes |
|---|
| 934 |
~~~~~~~~ |
|---|
| 935 |
|
|---|
| 936 |
Les objets ``Permission`` ont les mêmes méthodes standards d'accÚs aux données |
|---|
| 937 |
que les autres `modÚles Django`_. |
|---|
| 938 |
|
|---|
| 939 |
Données d'authentification dans les templates |
|---|
| 940 |
============================================= |
|---|
| 941 |
|
|---|
| 942 |
L'utilisateur actuellement authentifié et ses permissions sont disponibles dans |
|---|
| 943 |
le `contexte du template`_ quand vous utilisez ``RequestContext``. |
|---|
| 944 |
|
|---|
| 945 |
.. admonition:: Un peu de technique |
|---|
| 946 |
|
|---|
| 947 |
Techniquement, ces variables ne sont disponibles dans le contexte du template |
|---|
| 948 |
que si vous utilisez ``RequestContext`` *et* que votre rÚglage |
|---|
| 949 |
``TEMPLATE_CONTEXT_PROCESSORS`` contient |
|---|
| 950 |
``"django.core.context_processors.auth"``, qui est la valeur par défaut. Pour |
|---|
| 951 |
plus de détails, voir la `documentation de RequestContext`_. |
|---|
| 952 |
|
|---|
| 953 |
.. _documentation de RequestContext: ../templates_python/#subclassing-context-requestcontext |
|---|
| 954 |
|
|---|
| 955 |
Utilisateurs |
|---|
| 956 |
------------ |
|---|
| 957 |
|
|---|
| 958 |
L'utilisateur actuellement en ligne, soit une instance de ``User``, soit une |
|---|
| 959 |
instance de ``AnonymousUser``, est stocké dans la variable de template ``{{ user |
|---|
| 960 |
}}``:: |
|---|
| 961 |
|
|---|
| 962 |
{% if user.is_authenticated %} |
|---|
| 963 |
<p>Welcome, {{ user.username }}. Thanks for logging in.</p> |
|---|
| 964 |
{% else %} |
|---|
| 965 |
<p>Welcome, new user. Please log in.</p> |
|---|
| 966 |
{% endif %} |
|---|
| 967 |
|
|---|
| 968 |
Permissions |
|---|
| 969 |
----------- |
|---|
| 970 |
|
|---|
| 971 |
Les permissions de l'utilisateur actuellement en ligne sont stockées dans la |
|---|
| 972 |
variable de template ``{{ perms }}``. C'est une instance de |
|---|
| 973 |
``django.core.context_processors.PermWrapper``, qui est un proxy de permissions |
|---|
| 974 |
destiné aux templates. |
|---|
| 975 |
|
|---|
| 976 |
Dans l'objet ``{{ perms }}``, la recherche d'attributs simples est un proxy de |
|---|
| 977 |
``User.has_module_perms``. Cet exemple afficherait ``True`` si l'utilisateur en |
|---|
| 978 |
ligne avait une permission quelconque de l'application ``foo``:: |
|---|
| 979 |
|
|---|
| 980 |
{{ perms.foo }} |
|---|
| 981 |
|
|---|
| 982 |
La recherche d'attributs à deux niveaux est un proxy de ``User.has_perm``. Cet |
|---|
| 983 |
exemple afficherait ``True`` si l'utilisateur en ligne avait la permission |
|---|
| 984 |
``foo.can_vote``:: |
|---|
| 985 |
|
|---|
| 986 |
{{ perms.foo.can_vote }} |
|---|
| 987 |
|
|---|
| 988 |
Donc, vous pouvez vérifier les permissions dans des structures ``{% if %}`` de |
|---|
| 989 |
templates:: |
|---|
| 990 |
|
|---|
| 991 |
{% if perms.foo %} |
|---|
| 992 |
<p>You have permission to do something in the foo app.</p> |
|---|
| 993 |
{% if perms.foo.can_vote %} |
|---|
| 994 |
<p>You can vote!</p> |
|---|
| 995 |
{% endif %} |
|---|
| 996 |
{% if perms.foo.can_drive %} |
|---|
| 997 |
<p>You can drive!</p> |
|---|
| 998 |
{% endif %} |
|---|
| 999 |
{% else %} |
|---|
| 1000 |
<p>You don't have permission to do anything in the foo app.</p> |
|---|
| 1001 |
{% endif %} |
|---|
| 1002 |
|
|---|
| 1003 |
.. _contexte du template: ../templates_python/ |
|---|
| 1004 |
|
|---|
| 1005 |
Groupes |
|---|
| 1006 |
======= |
|---|
| 1007 |
|
|---|
| 1008 |
Les groupes permettent de grouper les utilisateurs par catégorie de façon à |
|---|
| 1009 |
attribuer des permissions ou autre label à ces utilisateurs. Un utilisateur peut |
|---|
| 1010 |
appartenir à un nombre quelconque de groupes. |
|---|
| 1011 |
|
|---|
| 1012 |
Un utilisateur appartenant à un groupe hérite automatiquement de toutes les |
|---|
| 1013 |
permissions de ce groupe. Par exemple, si le groupe ``Editeurs du site`` |
|---|
| 1014 |
possÚde la permission ``peut_editer_page_accueil``, alors tous les utilisateurs |
|---|
| 1015 |
de ce groupe auront cette permission. |
|---|
| 1016 |
|
|---|
| 1017 |
Au delà des permissions, les groupes offrent une façon commode de grouper les |
|---|
| 1018 |
utilisateurs par catégories pour leur affecter un label ou une fonctionnalité |
|---|
| 1019 |
étendue. Par exemple, vous pourriez créer un groupe ``'Special users'``, et |
|---|
| 1020 |
écrire du code qui leur autorise l'accÚs à une partie du site |
|---|
| 1021 |
réservée, ou permet d'envoyer un email à ce seul groupe. |
|---|
| 1022 |
|
|---|
| 1023 |
Messages |
|---|
| 1024 |
======== |
|---|
| 1025 |
|
|---|
| 1026 |
Le systÚme de messages est une façon légÚre de mettre en file d'attente des |
|---|
| 1027 |
messages pour un utilisateur donné. |
|---|
| 1028 |
|
|---|
| 1029 |
Un message est associé avec un objet ``User``. Il n'y pas de concept |
|---|
| 1030 |
d'expiration ou d'horodatage des messages. |
|---|
| 1031 |
|
|---|
| 1032 |
Les messages sont utilisés par l'administration de Django lorsque des actions se |
|---|
| 1033 |
sont déroulées correctement. Par exemple, ``"Le sondage Foo a été créé |
|---|
| 1034 |
correctement"`` est un message. |
|---|
| 1035 |
|
|---|
| 1036 |
L'API est simple: |
|---|
| 1037 |
|
|---|
| 1038 |
* Pour créer un nouveau message, utilisez |
|---|
| 1039 |
``user_obj.message_set.create(message='message_text')``. |
|---|
| 1040 |
* Pour retrouver ou effacer des messages, utilisez ``user_obj.get_and_delete_messages()``, |
|---|
| 1041 |
qui renvoie une liste des objets ``Message`` dans la file d'attente de |
|---|
| 1042 |
l'utilisateur (s'il y en a) et les efface de celle-ci. |
|---|
| 1043 |
|
|---|
| 1044 |
Dans cet exemple de vue, le systÚme enregistre un message pour l'utilisateur |
|---|
| 1045 |
aprÚs avoir créé une playlist:: |
|---|
| 1046 |
|
|---|
| 1047 |
def create_playlist(request, songs): |
|---|
| 1048 |
# Crée la playlist avec les morceaux (songs) passés en paramÚtre. |
|---|
| 1049 |
# ... |
|---|
| 1050 |
request.user.message_set.create(message="Votre playlist a été créée correctement.") |
|---|
| 1051 |
return render_to_response("playlists/create.html", |
|---|
| 1052 |
context_instance=RequestContext(request)) |
|---|
| 1053 |
|
|---|
| 1054 |
Quand vous utilisez ``RequestContext``, l'utilisateur actuellement en ligne et |
|---|
| 1055 |
ses messages sont disponibles dans le `contexte du template`_ sous la forme de |
|---|
| 1056 |
la variable de template ``{{ messages }}``. Voici un exemple de template qui |
|---|
| 1057 |
affichera les messages:: |
|---|
| 1058 |
|
|---|
| 1059 |
{% if messages %} |
|---|
| 1060 |
<ul> |
|---|
| 1061 |
{% for message in messages %} |
|---|
| 1062 |
<li>{{ message }}</li> |
|---|
| 1063 |
{% endfor %} |
|---|
| 1064 |
</ul> |
|---|
| 1065 |
{% endif %} |
|---|
| 1066 |
|
|---|
| 1067 |
Notez que ``RequestContext`` appelle ``get_and_delete_messages`` en coulisses, |
|---|
| 1068 |
donc tous les messages seront effacés même si vous ne les affichez pas. |
|---|
| 1069 |
|
|---|
| 1070 |
Enfin, notez que le systÚme de messages ne fonctionne que pour les utilisateurs |
|---|
| 1071 |
répertoriés dans la base de données. Pour envoyer des messages aux utilisateurs |
|---|
| 1072 |
anonymes, utilisez le `systÚme de sessions`_/ |
|---|
| 1073 |
|
|---|
| 1074 |
.. _systÚme de sessions: ../sessions/ |
|---|
| 1075 |
|
|---|
| 1076 |
Autres sources d'authentification |
|---|
| 1077 |
================================= |
|---|
| 1078 |
|
|---|
| 1079 |
Le systÚme d'authentification de Django est suffisant pour la plupart des cas |
|---|
| 1080 |
les plus courants, mais vous pouvez avoir besoin de le raccrocher à un autre |
|---|
| 1081 |
systÚme d'authentification, c'est-à -dire une autre source de noms d'utilisateurs |
|---|
| 1082 |
et de mots de passe, et/ou d'autres méthodes d'authentification. |
|---|
| 1083 |
|
|---|
| 1084 |
Par exemple, votre entreprise pourrait avoir un annuaire LDAP dans lequel sont |
|---|
| 1085 |
stockés un nom d'utilisateur et un mot de passe pour chaque salarié. Il est |
|---|
| 1086 |
clair qu'il serait trÚs pénible pour les administrateurs réseau et pour les |
|---|
| 1087 |
utilisateurs eux-mêmes d'avoir des comptes séparés dans l'annuaire LDAP et dans |
|---|
| 1088 |
les applications Django. |
|---|
| 1089 |
|
|---|
| 1090 |
Pour cette raison, et pour prendre en charge ce genre de situation, le systÚme |
|---|
| 1091 |
d'authentification Django vous permet de lui associer une autre source |
|---|
| 1092 |
d'authentification. Vous pouvez outrepasser les schémas de base de données de |
|---|
| 1093 |
Django, ou vous pouvez utiliser le systÚme par défaut de Django en tandem avec |
|---|
| 1094 |
d'autres systÚmes. |
|---|
| 1095 |
|
|---|
| 1096 |
Spécifier de nouveaux backends d'authentification |
|---|
| 1097 |
------------------------------------------------- |
|---|
| 1098 |
|
|---|
| 1099 |
Django gÚre en coulisses une liste de "backends d'authentification" qu'il |
|---|
| 1100 |
utilise pour l'authentification. Lorsque ``django.contrib.auth.authenticate()`` |
|---|
| 1101 |
est appelé -- comme il est expliqué dans "Comment authentifier un utilisateur" |
|---|
| 1102 |
ci-dessus --, Django essaie tous les backends d'authentification de la liste. Si |
|---|
| 1103 |
la premiÚre méthode d'authentification échoue, Django essaie la seconde, et |
|---|
| 1104 |
ainsi de suite, jusqu'à ce qu'il ait essayé tous les backends. |
|---|
| 1105 |
|
|---|
| 1106 |
La liste des backends d'authentification à utiliser est précisée dans la |
|---|
| 1107 |
variable ``AUTHENTICATION_BACKENDS``. Cette variable est un tuple de chemins |
|---|
| 1108 |
Python qui pointent vers des classes Python chargées de l'authentification. Ces |
|---|
| 1109 |
classes peuvent se trouver où vous voulez dans votre chemin Python. |
|---|
| 1110 |
|
|---|
| 1111 |
Par défaut, la valeur de ``AUTHENTICATION_BACKENDS`` est:: |
|---|
| 1112 |
|
|---|
| 1113 |
('django.contrib.auth.backends.ModelBackend',) |
|---|
| 1114 |
|
|---|
| 1115 |
C'est-à -dire le systÚme de base d'authentification, fondé sur la base |
|---|
| 1116 |
d'utilisateurs Django. |
|---|
| 1117 |
|
|---|
| 1118 |
L'ordre des backends dans le tuple ``AUTHENTICATION_BACKENDS`` a une importance |
|---|
| 1119 |
dans la mesure où si un couple utilisateur et mot de passe est valide dans |
|---|
| 1120 |
plusieurs backends, Django s'arrêtera au premier qui permet de le vérifier. |
|---|
| 1121 |
|
|---|
| 1122 |
Comment écrire un backend d'authentification |
|---|
| 1123 |
-------------------------------------------- |
|---|
| 1124 |
|
|---|
| 1125 |
Un backend d'authentification est une classe qui implémente deux méthodes: |
|---|
| 1126 |
``get_user(user_id)`` et ``authenticate(**credentials)``. |
|---|
| 1127 |
|
|---|
| 1128 |
La méthode ``get_user`` prend une ``user_id`` -- qui peut être un nom d'utilisateur, |
|---|
| 1129 |
une ID dans une base de données ou autre -- et renvoie un objet ``User``. |
|---|
| 1130 |
|
|---|
| 1131 |
La méthode ``authenticate`` prend en argument les valeurs d'authentification. La |
|---|
| 1132 |
plupart du temps, ce sera simplement quelque chose du genre:: |
|---|
| 1133 |
|
|---|
| 1134 |
class MyBackend: |
|---|
| 1135 |
def authenticate(self, username=None, password=None): |
|---|
| 1136 |
# Vérifie le couple username/password et renvoie un objet User. |
|---|
| 1137 |
|
|---|
| 1138 |
Mais elle peut aussi authentifier à partir d'un jeton, comme dans:: |
|---|
| 1139 |
|
|---|
| 1140 |
class MyBackend: |
|---|
| 1141 |
def authenticate(self, token=None): |
|---|
| 1142 |
# Vérifie la validité du jeton, et renvoie un objet User. |
|---|
| 1143 |
|
|---|
| 1144 |
Dans tous les cas, ``authenticate`` doit vérifier la validité des données |
|---|
| 1145 |
d'authentification fournies, et doit renvoyer un objet ``User`` qui correspond à |
|---|
| 1146 |
ces données si elles sont valides. Si elles ne sont pas valides, la méthode |
|---|
| 1147 |
doit renvoyer ``None``. |
|---|
| 1148 |
|
|---|
| 1149 |
Le systÚme d'administration de Django est trÚs fortement lié à l'objet Django |
|---|
| 1150 |
``User`` décrit au début de ce document. Pour le moment, la meilleure façon de |
|---|
| 1151 |
gérer cette contrainte est de créer un objet ``User`` Django pour chacun des |
|---|
| 1152 |
objets de votre backend (par exemple votre annuaire LDAP, votre base SQL |
|---|
| 1153 |
externe, etc.). Vous pouvez soit écrire un script qui le fait à l'avance, soit |
|---|
| 1154 |
prévoir que votre méthode ``authenticate`` le fasse la premiÚre fois que votre |
|---|
| 1155 |
utilisateur se connecte. |
|---|
| 1156 |
|
|---|
| 1157 |
Voici un exemple de backend qui authentifie à partir d'un nom d'utilisateur et |
|---|
| 1158 |
d'un mot de passe définis dans votre fichier ``settings.py`` et crée un objet |
|---|
| 1159 |
Django ``User`` la premiÚre fois que l'utilisateur cherche à se connecter:: |
|---|
| 1160 |
|
|---|
| 1161 |
from django.conf import settings |
|---|
| 1162 |
from django.contrib.auth.models import User, check_password |
|---|
| 1163 |
|
|---|
| 1164 |
class SettingsBackend: |
|---|
| 1165 |
""" |
|---|
| 1166 |
Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD. |
|---|
| 1167 |
|
|---|
| 1168 |
Use the login name, and a hash of the password. For example: |
|---|
| 1169 |
|
|---|
| 1170 |
ADMIN_LOGIN = 'admin' |
|---|
| 1171 |
ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de' |
|---|
| 1172 |
""" |
|---|
| 1173 |
def authenticate(self, username=None, password=None): |
|---|
| 1174 |
login_valid = (settings.ADMIN_LOGIN == username) |
|---|
| 1175 |
pwd_valid = check_password(password, settings.ADMIN_PASSWORD) |
|---|
| 1176 |
if login_valid and pwd_valid: |
|---|
| 1177 |
try: |
|---|
| 1178 |
user = User.objects.get(username=username) |
|---|
| 1179 |
except User.DoesNotExist: |
|---|
| 1180 |
# Create a new user. Note that we can set password |
|---|
| 1181 |
# to anything, because it won't be checked; the password |
|---|
| 1182 |
# from settings.py will. |
|---|
| 1183 |
user = User(username=username, password='get from settings.py') |
|---|
| 1184 |
user.is_staff = True |
|---|
| 1185 |
user.is_superuser = True |
|---|
| 1186 |
user.save() |
|---|
| 1187 |
return user |
|---|
| 1188 |
return None |
|---|
| 1189 |
|
|---|
| 1190 |
def get_user(self, user_id): |
|---|
| 1191 |
try: |
|---|
| 1192 |
return User.objects.get(pk=user_id) |
|---|
| 1193 |
except User.DoesNotExist: |
|---|
| 1194 |
return None |
|---|
| 1195 |
|
|---|
| 1196 |
Gérer les autorisations dans les backends personnalisés |
|---|
| 1197 |
------------------------------------------------------- |
|---|
| 1198 |
|
|---|
| 1199 |
Les backends d'authentification personnalisés peuvent fournir leurs propres |
|---|
| 1200 |
permissions. |
|---|
| 1201 |
|
|---|
| 1202 |
Le modÚle utilisateur déléguera les fonctions de recherche de permissions |
|---|
| 1203 |
(``get_group_permissions()``, ``get_all_permissions()``, ``has_perm()``, et |
|---|
| 1204 |
``has_module_perms()``) a tout backend d'authentification qui implémente ces |
|---|
| 1205 |
fonctions. |
|---|
| 1206 |
|
|---|
| 1207 |
Les permissions de l'objet ``User`` seront un surensemble de toutes les |
|---|
| 1208 |
permissions retournées par tous les backends. Django accordera a un utilisateur |
|---|
| 1209 |
toute permission accordée par un quelconque des backends. |
|---|
| 1210 |
|
|---|
| 1211 |
Le backend d'exemple ci-dessus pourrait mettre en place des permissions pour |
|---|
| 1212 |
l'administrateur de façon trÚs simple:: |
|---|
| 1213 |
|
|---|
| 1214 |
class SettingsBackend: |
|---|
| 1215 |
|
|---|
| 1216 |
# ... |
|---|
| 1217 |
|
|---|
| 1218 |
def has_perm(self, user_obj, perm): |
|---|
| 1219 |
if user_obj.username == settings.ADMIN_LOGIN: |
|---|
| 1220 |
return True |
|---|
| 1221 |
else: |
|---|
| 1222 |
return False |
|---|
| 1223 |
|
|---|
| 1224 |
Ce code donne toutes les permissions à l'utilisateur qui a obtenu l'accÚs dans |
|---|
| 1225 |
l'exemple précédent. Notez que les fonctions d'authentification des backends |
|---|
| 1226 |
prennent toutes l'objet ``User`` comme argument, et qu'elles acceptent également |
|---|
| 1227 |
les mêmes arguments que ceux qui sont fournis aux fonctions associées du |
|---|
| 1228 |
``User``. |
|---|
| 1229 |
|
|---|
| 1230 |
Une implémentation complÚte de systÚme d'autorisation est fournie dans |
|---|
| 1231 |
`django/contrib/auth/backends.py`_, qui est le backend par défaut et interroge |
|---|
| 1232 |
la table ``auth_permission`` la plupart du temps. |
|---|
| 1233 |
|
|---|
| 1234 |
.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py |
|---|
| 1235 |
|
|---|
| 1236 |
.. vim:tw=80:encoding=utf8: |
|---|