Utilisation du système d’authentification de Django¶
Ce document présente l’utilisation du système d’authentification de Django dans sa configuration par défaut. Cette configuration a évolué afin de pouvoir répondre aux besoins les plus courants des projets, elle est capable de gérer une large palette de tâches, et elle possède une implémentation soigneuse des mots de passe et des permissions. Pour les projets où les besoins en terme d’authentification divergent de la configuration par défaut, Django permet d”étendre et de personnaliser l’authentification de manière approfondie.
L’authentification de Django fournit à la fois l’authentification et l’autorisation, regroupés sous le terme général de système d’authentification, dans la mesure où ces fonctions sont assez étroitement liées.
Objets utilisateurs¶
Les objets User
se trouvent au cœur du système d’authentification. Ils représentent typiquement les personnes qui interagissent avec votre site et sont utilisés pour activer des fonctionnalités comme la restriction d’accès, l’enregistrement de profils utilisateurs, l’association de contenus avec leur créateur, etc. Une seule classe d’utilisateurs existe dans le système d’authentification de Django ; cela signifie donc que les « super-utilisateurs » ('superusers'
) ou les membres des équipes d’administration du site ( 'staff'
) ne sont que des objets utilisateur normaux ayant certains attributs définis, et non pas une classe différente d’objet utilisateur.
Les attributs principaux de l’utilisateur par défaut sont :
Consultez la documentation complète de l'API
pour une référence exhaustive ; la documentation ci-après est plus orientée sur les tâches.
Création d’utilisateurs¶
La manière la plus directe de créer des utilisateurs est d’utiliser la fonction utilitaire create_user()
:
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
# At this point, user is a User object that has already been saved
# to the database. You can continue to change its attributes
# if you want to change other fields.
>>> user.last_name = 'Lennon'
>>> user.save()
Si vous avez installé l’interface d’administration de Django, vous pouvez aussi créer des utilisateurs interactivement.
Création de superutilisateurs¶
Les superutilisateurs peuvent être créés à l’aide de la commande createsuperuser
:
$ python manage.py createsuperuser --username=joe --email=joe@example.com
Vous devrez saisir un mot de passe. Après l’avoir fait, l’utilisateur sera immédiatement créé. Si vous omettez les options --username
ou --email
, vous devrez aussi renseigner ces valeurs.
Modification des mots de passe¶
Django ne stocke pas de mots de passe bruts (en clair) dans le modèle d’utilisateur, mais uniquement une empreinte hachée (voir la documentation sur la façon dont sont gérés les mots de passe pour des détails plus complets). C’est pourquoi il faut éviter de manipuler directement l’attribut password
de l’utilisateur et qu’une fonction utilitaire est employée pour créer un utilisateur.
Pour changer le mot de passe d’un utilisateur, vous disposez de plusieurs options :
manage.py changepassword *nom d'utilisateur*
offre une méthode permettant de changer le mot de passe d’un utilisateur dans une ligne de commande. Vous serez invité à changer le mot de passe de l’utilisateur indiqué en le saisissant deux fois. Si les deux saisies correspondent, le nouveau mot de passe sera immédiatement défini. Si vous n’indiquez pas de nom d’utilisateur, la commande essaie de changer le mot de passe de l’utilisateur dont le nom correspond à l’utilisateur système en cours.
Il est aussi possible de changer un mot de passe de façon programmatique, en utilisant set_password()
:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()
Si l’interface d’administration de Django est installée, vous pouvez aussi changer les mots de passe des utilisateurs dans les pages d’administration du système d’authentification.
Django fournit également des vues et des formulaires permettant aux utilisateurs de changer leur propre mot de passe.
Le changement de mot de passe d’un utilisateur déconnecte toutes ses sessions. Voir Invalidation de session lors du changement de mot de passe pour plus de détails.
Authentification des utilisateurs¶
-
authenticate
(request=None, **credentials)¶ Utilisez
authenticate()
pour vérifier un jeu de données d’authentification. Cette méthode accepte les données d’authentification sous forme de paramètres nommés,username
etpassword
pour la configuration par défaut, vérifie ces données avec chaque moteur d’authentification et renvoie un objetUser
si l’authentification est valide pour un des moteurs. Si aucun moteur n’accepte l’authentification ou si un moteur génèrePermissionDenied
, la méthode renvoieNone
. Par exemple :from django.contrib.auth import authenticate user = authenticate(username='john', password='secret') if user is not None: # A backend authenticated the credentials else: # No backend authenticated the credentials
request
est un objetHttpRequest
facultatif qui est transmis à la méthodeauthenticate()
des moteurs d’authentification.Note
Ceci est une manière d’authentifier un jeu de données d’authentification à un bas niveau ; par exemple, c’est ce qui est utilisé par
RemoteUserMiddleware
. Vous n’aurez probablement pas l’usage de cette méthode, sauf si vous écrivez votre propre système d’authentification. Si vous recherchez un moyen de connecter un utilisateur, utilisez plutôt la classeLoginView
.
Permissions et autorisations¶
Django contient un système intégré de permissions. Il permet d’attribuer des permissions à des utilisateurs ou des groupes d’utilisateurs particuliers.
Ce système est utilisé par le site d’administration de Django, mais vous avez tout loisir de l’utiliser dans votre propre code.
Le site d’administration de Django utilise les permissions ainsi :
- L’accès à l’affichage d’un objet est limité aux utilisateurs possédant la permission « view » ou « change » pour ce type d’objet.
- L’accès au formulaire d’ajout et l’ajout d’objet sont limités aux utilisateurs possédant la permission « add » pour ce type d’objet.
- L’accès à la liste des objets pour modification, au formulaire de modification et la modification d’un objet sont limités aux utilisateurs possédant la permission « change » pour ce type d’objet.
- L’accès à la suppression d’un objet est limité aux utilisateurs possédant la permission « delete » pour ce type d’objet.
Les permissions peuvent non seulement être attribuées par type d’objet, mais aussi par instance d’objet spécifique. En utilisant les méthodes has_view_permission()
, has_add_permission()
, has_change_permission()
et has_delete_permission()
fournies par la classe ModelAdmin
, il est possible de personnaliser les permissions pour différentes instances d’objets du même type.
Les objets User
possèdent deux champs plusieurs-à-plusieurs : groups
et user_permissions
. Les objets User
peuvent accéder à leurs objets liés de la même façon que pour tout autre modèle Django:
myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()
Permissions par défaut¶
Quand l’application django.contrib.auth
figure dans le réglage INSTALLED_APPS
, elle s’assure que les quatre permissions par défaut (« add », « change », « delete » et « view ») soient créées pour chaque modèle Django défini dans toutes les applications installées.
Ces permissions seront créées lorsque vous lancez manage.py migrate
; au premier lancement de migrate
après l’ajout de django.contrib.auth
à INSTALLED_APPS
, les permissions par défaut seront créées pour tous les modèles précédemment installés de même que pour tout nouveau modèle installé à ce moment-là. Par la suite, chaque nouvelle exécution de manage.py migrate
crée les permissions par défaut pour les nouveaux modèles (la fonction qui crée les permissions est connectée au signal post_migrate
).
En supposant qu’une application ait l’attribut app_label
foo
et qu’un modèle soit nommé Bar
, voici comment il faut tester les permissions de base :
- ajout :
user.has_perm('foo.add_bar')
- modification :
user.has_perm('foo.change_bar')
- suppression :
user.has_perm('foo.delete_bar')
- affichage :
user.has_perm('foo.view_bar')
Le modèle Permission
est rarement accédé directement.
Groupes¶
Les modèles django.contrib.auth.models.Group
sont une manière générique de segmenter les utilisateurs afin de pouvoir leur attribuer des permissions ou de les désigner par un nom défini. Un utilisateur peut appartenir à autant de groupes que nécessaire.
Un utilisateur d’un groupe reçoit automatiquement les permissions attribuées à ce groupe. Par exemple, si le groupe Éditeurs du site
possède la permission can_edit_home_page
, tout utilisateur membre du groupe possédera cette permission.
Au-delà des permissions, les groupes sont un bon moyen de regrouper les utilisateurs sous un nom défini, afin de leur attribuer certaines fonctionnalités particulières. Par exemple, vous pourriez créer un groupe Utilisateurs spéciaux
et écrire ensuite du code qui leur donne accès à une section réservée aux membres sur le site, ou leur envoyer des courriels s’adressant uniquement aux membres.
Création programmatique de permissions¶
Bien que des permissions personnalisées puissent être définies dans la classe Meta
d’un modèle, il est aussi possible de créer directement des permissions. Par exemple, vous pouvez créer la permission can_publish
d’un modèle BlogPost
dans myapp
:
from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
codename='can_publish',
name='Can Publish Posts',
content_type=content_type,
)
La permission peut ensuite être attribuée à un User
par son attribut user_permissions
ou à un Group
par son attribut permissions
.
Les modèles mandataires ont besoin de leur propre type de contenu
Si vous souhaitez créer des permission pour un modèle mandataire, passez for_concrete_model=False
à ContentTypeManager.get_for_model()
pour obtenir le type ContentType
approprié
content_type = ContentType.objects.get_for_model(BlogPostProxy, for_concrete_model=False)
Mise en cache des permissions¶
Le moteur ModelBackend
met en cache les permissions de l’objet utilisateur la première fois que ces permissions doivent être consultées. Cela convient généralement bien au cycle requête-réponse car en principe les permissions ne sont pas consultées immédiatement après avoir été ajoutées (dans l’interface d’administration par exemple). Si vous ajoutez des permissions et que vous les consultez immédiatement après, par exemple dans un test ou une vue, la solution la plus simple est de récupérer une nouvelle fois l’objet utilisateur à partir de la base de données. Par exemple :
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from myapp.models import BlogPost
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm('myapp.change_blogpost')
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.get(
codename='change_blogpost',
content_type=content_type,
)
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('myapp.change_blogpost') # False
# Request new instance of User
# Be aware that user.refresh_from_db() won't clear the cache.
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm('myapp.change_blogpost') # True
...
Modèles mandataires¶
Les modèles mandataires fonctionnent exactement de la même manière que les modèles concrets. Les permissions sont créées en utilisant le type de contenu propre au modèle mandataire. Les modèles mandataires n’héritent pas des permissions du modèle concret qu’ils étendent
class Person(models.Model):
class Meta:
permissions = [('can_eat_pizzas', 'Can eat pizzas')]
class Student(Person):
class Meta:
proxy = True
permissions = [('can_deliver_pizzas', 'Can deliver pizzas')]
>>> # Fetch the content type for the proxy model.
>>> content_type = ContentType.objects.get_for_model(Student, for_concrete_model=False)
>>> student_permissions = Permission.objects.filter(content_type=content_type)
>>> [p.codename for p in student_permissions]
['add_student', 'change_student', 'delete_student', 'view_student',
'can_deliver_pizzas']
>>> for permission in student_permissions:
... user.user_permissions.add(permission)
>>> user.has_perm('app.add_person')
False
>>> user.has_perm('app.can_eat_pizzas')
False
>>> user.has_perms(('app.add_student', 'app.can_deliver_pizzas'))
True
Authentification dans les requêtes Web¶
Django utilise les sessions et le système de middleware pour brancher le système d’authentification dans les objets requête
.
Un attribut request.user
représentant l’utilisateur actuel est défini sur chaque objet requête. Si cet utilisateur ne s’est pas connecté, cet attribut sera constitué d’une instance de AnonymousUser
, sinon il s’agira d’une instance de User
.
Vous pouvez les différencier par la méthode is_authenticated
, comme ceci :
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
Connexion d’un utilisateur¶
Si vous disposez d’un utilisateur authentifié que vous voulez faire correspondre à la session en cours, utilisez la fonction login()
.
-
login
(request, user, backend=None)¶ Pour connecter un utilisateur à partir d’une vue, utilisez
login()
. Cette fonction accepte un objetHttpRequest
et un objetUser
.login()
enregistre l’identifiant de l’utilisateur dans la session en employant l’infrastructure des sessions de Django.Notez que toute information définie durant la session anonyme d’un utilisateur est conservée dans la session à la suite du processus de connexion.
Cet exemple montre comment utiliser à la fois
authenticate()
etlogin()
:from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # Redirect to a success page. ... else: # Return an 'invalid login' error message. ...
Choix du moteur d’authentification¶
Lorsqu’un utilisateur se connecte, son identifiant et le moteur utilisé pour son authentification sont enregistrés dans la session de l’utilisateur. Cela permet au même moteur d’authentification de récupérer les détails de l’utilisateur lors d’une prochaine requête. Le moteur d’authentification qui sera enregistré dans la session est choisi comme ceci :
- Si le paramètre
backend
factultatif est fourni, c’est celui-là qui est utilisé. - Si un attribut
user.backend
existe, c’est celui-là qui est utilisé. Cela permet de combinerauthenticate()
etlogin()
:authenticate()
définit l’attributuser.backend
sur l’objet utilisateur qu’il renvoie. - S’il n’y a qu’un seul moteur dans
AUTHENTICATION_BACKENDS
, c’est celui-là qui est utilisé. - Sinon, une exception est produite.
Dans les deux premiers cas, la valeur du paramètre backend
ou l’attribut user.backend
doit correspondre à une chaîne de chemin pointé (comme la syntaxe dans AUTHENTICATION_BACKENDS
), et non pas la classe de moteur réelle.
Déconnexion d’un utilisateur¶
-
logout
(request)¶ Pour déconnecter un utilisateur qui a été connecté par
django.contrib.auth.login()
, utilisezdjango.contrib.auth.logout()
depuis la vue. Cette fonction accepte un objetHttpRequest
et ne renvoie aucune valeur. Exemple :from django.contrib.auth import logout def logout_view(request): logout(request) # Redirect to a success page.
Notez que
logout()
ne signale pas d’erreur si l’utilisateur n’était pas connecté.Lorsque vous appelez
logout()
, les données de session de la requête en cours sont complètement effacées. Ce comportement empêche une autre personne d’utiliser le même navigateur Web pour se connecter et obtenir accès aux données de session de l’utilisateur précédent. Si vous souhaitez placer des informations dans la session qui doivent être disponibles pour l’utilisateur immédiatement après une déconnexion, faites-le après avoir appelédjango.contrib.auth.logout()
.
Restriction d’accès aux utilisateurs connectés¶
La manière brute¶
La manière directe de limiter l’accès à certaines pages est de vérifier request.user.is_authenticated
et de rediriger l’utilisateur vers la page de connexion le cas échéant :
from django.conf import settings
from django.shortcuts import redirect
def my_view(request):
if not request.user.is_authenticated:
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
# ...
…ou d’afficher un message d’erreur :
from django.shortcuts import render
def my_view(request):
if not request.user.is_authenticated:
return render(request, 'myapp/login_error.html')
# ...
Le décorateur login_required
¶
-
login_required
(redirect_field_name='next', login_url=None)¶ Comme raccourci, vous pouvez utiliser le décorateur
login_required()
bien pratique :from django.contrib.auth.decorators import login_required @login_required def my_view(request): ...
login_required()
effectue ceci :- Si l’utilisateur n’est pas connecté, il redirige vers
settings.LOGIN_URL
en transmettant le chemin absolu dans la chaîne de requête. Exemple :/accounts/login/?next=/polls/3/
. - Si l’utilisateur est connecté, il exécute la vue normalement. Le code de la vue peut légitimement considérer l’utilisateur comme connecté.
Par défaut, le chemin vers lequel l’utilisateur doit être redirigé après un processus de connexion réussi est stocké dans le paramètre de chaîne de requête nommé
"next"
. Si vous préférez que ce paramètre soit nommé différemment,login_required()
accepte un paramètre facultatifredirect_field_name
:from django.contrib.auth.decorators import login_required @login_required(redirect_field_name='my_redirect_field') def my_view(request): ...
Notez que si vous indiquez une valeur pour
redirect_field_name
, il faudra très probablement aussi personnaliser le gabarit de connexion, dans la mesure où la variable de contexte du gabarit qui stocke le chemin de redirection utilise la valeur deredirect_field_name
comme clé à la place de"next"
(la valeur par défaut).login_required()
accepte également un paramètre facultatiflogin_url
. Exemple :from django.contrib.auth.decorators import login_required @login_required(login_url='/accounts/login/') def my_view(request): ...
Notez que si vous ne renseignez pas le paramètre
login_url
, vous devez vous assurer que le réglagesettings.LOGIN_URL
et votre vue de connexion sont correctement liés. Par exemple, en utilisant les paramètres par défaut, ajoutez les lignes suivantes dans votre configuration d’URL :from django.contrib.auth import views as auth_views path('accounts/login/', auth_views.LoginView.as_view()),
Le réglage
settings.LOGIN_URL
accepte également des noms de fonction vue et des motifs d’URL nommés. Cela permet de déplacer librement la vue de connexion dans la configuration d’URL sans avoir besoin de mettre à jour le réglage.- Si l’utilisateur n’est pas connecté, il redirige vers
Note
Le décorateur login_required
ne vérifie PAS le drapeau is_active
d’un utilisateur, mais le moteur AUTHENTICATION_BACKENDS
par défaut rejette les utilisateurs inactifs.
Voir aussi
Si vous écrivez des vues personnalisées pour le site d’administration de Django (ou que vous avez besoin des mêmes contrôles d’autorisation que les vues intégrées utilisent), le décorateur django.contrib.admin.views.decorators.staff_member_required()
pourrait vous être encore plus utile que login_required()
.
La classe mixin LoginRequired
¶
Lors de l’utilisation des vues fondées sur les classes, vous pouvez obtenir le même comportement qu’avec login_required
en utilisant LoginRequiredMixin
. Cette classe mixin doit se trouver à la position la plus à gauche de la chaîne d’héritage.
-
class
LoginRequiredMixin
¶ Si une vue utilise cette classe mixin, toutes les requêtes par des utilisateurs non authentifiés seront redirigées vers la page de connexion ou traitées comme des erreurs HTTP 403 Forbidden, selon le paramètre
raise_exception
.Vous pouvez définir n’importe lequel des paramètres de
AccessMixin
pour personnaliser le traitement des utilisateurs non authentifiés :from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): login_url = '/login/' redirect_field_name = 'redirect_to'
Note
Comme pour le décorateur login_required
, cette classe mixin ne vérifie PAS le drapeau is_active
d’un utilisateur, mais le moteur AUTHENTICATION_BACKENDS
par défaut rejette les utilisateurs inactifs.
Restriction d’accès aux utilisateurs connectés passant un test¶
Pour limiter l’accès en fonction d’une certaine permission ou d’un test quelconque, le procédé est presque identique à celui décrit dans la section précédente.
Vous pouvez effectuer le test sur request.user
directement dans la vue. Par exemple, cette vue vérifie que l’utilisateur possède bien une adresse électronique dans le domaine prévu et, dans le cas contraire, redirige vers la page de connexion :
from django.shortcuts import redirect
def my_view(request):
if not request.user.email.endswith('@example.com'):
return redirect('/login/?next=%s' % request.path)
# ...
-
user_passes_test
(test_func, login_url=None, redirect_field_name='next')¶ Comme raccourci, vous pouvez utiliser le décorateur
user_passes_test
qui procède à une redirection lorsque la fonction décorée renvoieFalse
:from django.contrib.auth.decorators import user_passes_test def email_check(user): return user.email.endswith('@example.com') @user_passes_test(email_check) def my_view(request): ...
user_passes_test()
requiert un paramètre : un exécutable acceptant un objetUser
et renvoyantTrue
si l’utilisateur est autorisé à voir la page. Notez queuser_passes_test()
ne contrôle pas d’office que l’objetUser
n’est pas anonyme.user_passes_test()
accepte deux paramètres facultatifs :login_url
- Permet d’indiquer l’URL vers laquelle les utilisateurs ne passant pas le test seront redirigés. Cela peut être une page de connexion, la valeur par défaut étant
settings.LOGIN_URL
. redirect_field_name
- Comme pour
login_required()
. Si vous définissez ce paramètre àNone
, il ne sera pas présent dans l’URL, ce qui peut être intéressant si vous redirigez des utilisateurs qui ne passent pas le test vers une page ne servant pas à se connecter et où il n’y a pas de concept de « page suivante ».
Par exemple :
@user_passes_test(email_check, login_url='/login/') def my_view(request): ...
-
class
UserPassesTestMixin
¶ Quand on utilise les vues fondées sur les classes, on peut utiliser la classe
UserPassesTestMixin
pour faire cela.-
test_func
()¶ Vous devez surcharger la méthode
test_func()
de la classe pour fournir le test qui sera effectué. De plus, vous pouvez définir n’importe lequel des paramètres deAccessMixin
pour personnaliser le traitement des utilisateurs non authentifiés :from django.contrib.auth.mixins import UserPassesTestMixin class MyView(UserPassesTestMixin, View): def test_func(self): return self.request.user.email.endswith('@example.com')
-
get_test_func
()¶ Vous pouvez aussi surcharger la méthode
get_test_func()
si vous souhaitez que la classe mixin utilise une autre méthode pour cette vérification (au lieu detest_func()
).
Accumulation de
UserPassesTestMixin
En raison de l’implémentation de
UserPassesTestMixin
, il n’est pas possible d’en combiner plusieurs dans la chaîne d’héritage. Le code suivant ne fonctionnera PAS :class TestMixin1(UserPassesTestMixin): def test_func(self): return self.request.user.email.endswith('@example.com') class TestMixin2(UserPassesTestMixin): def test_func(self): return self.request.user.username.startswith('django') class MyView(TestMixin1, TestMixin2, View): ...
Si
TestMixin1
appelaitsuper()
et prenait en compte le résultat,TestMixin1
ne fonctionnerait plus de façon autonome.-
Le décorateur permission_required
¶
-
permission_required
(perm, login_url=None, raise_exception=False)¶ Il est relativement courant de devoir vérifier que l’utilisateur dispose d’une certaine permission. À cet effet, Django fournit un raccourci : le décorateur
permission_required()
:from django.contrib.auth.decorators import permission_required @permission_required('polls.add_choice') def my_view(request): ...
Comme pour la méthode
has_perm()
, les noms de permission ont la forme"<étiquette application>.<code permission>"
(par ex.polls.add_choice
pour une permission d’un modèle de l’applicationpolls
).Le décorateur accepte aussi une liste de permissions, auquel cas l’utilisateur doit posséder toutes les permissions de la liste afin d’avoir accès à la vue.
Notez que
permission_required()
accepte également un paramètre facultatiflogin_url
:from django.contrib.auth.decorators import permission_required @permission_required('polls.add_choice', login_url='/loginpage/') def my_view(request): ...
Comme pour le décorateur
login_required()
, la valeur par défaut delogin_url
estsettings.LOGIN_URL
.Si le paramètre
raise_exception
est présent, le décorateur génère une exceptionPermissionDenied
(permission refusée), déclenchant la vue 403 (HTTP Forbidden) au lieu de rediriger vers la page de connexion.Si vous souhaitez utiliser
raise_exception
tout en laissant aux utilisateurs une chance de se connecter, vous pouvez ajouter le décorateurlogin_required()
:from django.contrib.auth.decorators import login_required, permission_required @login_required @permission_required('polls.add_choice', raise_exception=True) def my_view(request): ...
Ceci évite aussi une boucle de redirection lorsque
redirect_authenticated_user=True
dansLoginView
et que l’utilisateur connecté ne possède pas toutes les permissions requises.
La classe mixin PermissionRequiredMixin
¶
Pour appliquer des contrôles de permission aux vues fondées sur les classes, vous pouvez utiliser la classe PermissionRequiredMixin
:
-
class
PermissionRequiredMixin
¶ Cette classe mixin, tout comme le décorateur
permission_required
, contrôle si l’utilisateur accédant à une vue possède toutes les permissions indiquées. La permission (ou une itération de permissions) doit être indiquée dans le paramètrepermission_required
:from django.contrib.auth.mixins import PermissionRequiredMixin class MyView(PermissionRequiredMixin, View): permission_required = 'polls.add_choice' # Or multiple of permissions: permission_required = ('polls.view_choice', 'polls.change_choice')
Vous pouvez définir n’importe lequel des paramètres de
AccessMixin
pour personnaliser le traitement des utilisateurs non authentifiés.Vous pouvez également surcharger ces méthodes :
-
get_permission_required
()¶ Renvoie une itération de noms de permissions utilisés par la classe mixin. Il s’agit par défaut du contenu de l’attribut
permission_required
, converti en tuple si nécessaire.
-
has_permission
()¶ Renvoie une valeur booléenne indiquant si l’utilisateur actuel a la permission d’exécuter la vue décorée. Par défaut, ceci renvoie le résultat de l’appel à
has_perms()
avec la liste des permissions renvoyées parget_permission_required()
.
-
Redirection des requêtes non autorisées dans les vues fondées sur les classes¶
Pour faciliter la gestion des restrictions d’accès dans les vues fondées sur les classes, la classe AccessMixin
peut être utilisée pour configurer le comportement d’une vue lorsque son accès est refusé. Les utilisateurs authentifiés reçoivent une réponse HTTP 403 Forbidden. Les utilisateurs anonymes sont redirigés vers la page de connexion ou reçoivent une réponse HTTP 403, en fonction de l’attribut raise_exception
.
-
class
AccessMixin
¶ -
login_url
¶ Valeur de renvoi par défaut de
get_login_url()
. ContientNone
par défaut auquel casget_login_url()
se rabat sur le contenu desettings.LOGIN_URL
.
-
permission_denied_message
¶ Valeur de renvoi par défaut de
get_permission_denied_message()
. Contient une chaîne vide par défaut.
-
redirect_field_name
¶ Valeur de renvoi par défaut de
get_redirect_field_name()
. Contient"next"
par défaut.
-
raise_exception
¶ Si cet attribut est défini à
True
, une exceptionPermissionDenied
est produite lorsque les conditions ne sont pas remplies. Si la valeur estFalse
(par défaut), les utilisateurs anonymes sont redirigés vers la page de connexion.
-
get_login_url
()¶ Renvoie l’URL vers laquelle les utilisateurs ne passant pas le test seront redirigés. Renvoie
login_url
le cas échéant, sinonsettings.LOGIN_URL
.
-
get_permission_denied_message
()¶ Lorsque
raise_exception
vautTrue
, cette méthode peut être utilisée pour contrôler le message d’erreur transmis au gestionnaire d’erreur pour y être affiché à destination de l’utilisateur. Par défaut, renvoie l’attributpermission_denied_message
.
-
get_redirect_field_name
()¶ Renvoie le nom du paramètre de requête qui contiendra l’URL vers laquelle l’utilisateur sera redirigé à la suite d’une connexion réussie. Si cette valeur est
None
, aucun paramètre de requête ne sera ajouté. Renvoie par défaut l’attributredirect_field_name
.
-
handle_no_permission
()¶ En fonction de la valeur de
raise_exception
, cette méthode peut soit générer une exceptionPermissionDenied
, soit rediriger l’utilisateur verslogin_url
, incluant potentiellementredirect_field_name
si celui-ci est défini.
-
Invalidation de session lors du changement de mot de passe¶
Si votre AUTH_USER_MODEL
hérite de AbstractBaseUser
ou implémente sa propre méthode get_session_auth_hash()
, les sessions authentifiées comprendront la valeur de hachage renvoyée par cette fonction. Dans le cas d’un AbstractBaseUser
, il s’agit d’une empreinte HMAC du champ de mot de passe. Django vérifie que la valeur de hachage dans la session de chaque requête correspond à celle qui est calculée durant la requête. Cela permet à un utilisateur de se déconnecter de l’ensemble de ses sessions en changeant son mot de passe.
Les vues fournies par défaut avec Django pour le changement de mot de passe, PasswordChangeView
et user_change_password
du module django.contrib.auth
, mettent à jour la session avec la valeur de hachage du nouveau mot de passe pour que l’utilisateur qui change son mot de passe ne soit pas déconnecté. Si vous avez une vue personnalisée pour le changement de mot de passe et que vous souhaitez avoir un comportement similaire, utilisez la fonction update_session_auth_hash()
.
-
update_session_auth_hash
(request, user)¶ Cette fonction accepte en entrée la requête actuelle ainsi que l’objet utilisateur mis à jour et à partir duquel la nouvelle valeur de hachage de la session sera calculée ; elle met à jour la valeur de hachage de la session. Elle se charge aussi d’alterner la clé de session afin qu’un cookie de session volé soit invalidé :
Exemple d’utilisation :
from django.contrib.auth import update_session_auth_hash def password_change(request): if request.method == 'POST': form = PasswordChangeForm(user=request.user, data=request.POST) if form.is_valid(): form.save() update_session_auth_hash(request, form.user) else: ...
Note
Comme get_session_auth_hash()
se base sur SECRET_KEY
, la mise à jour de la clé secrète sur votre site invalide toutes les sessions existantes.
Vues d’authentification¶
Django fournit plusieurs vues permettant de gérer la connexion, la déconnexion et le traitement des mots de passe. Elles font appel aux formulaires d’authentification intégrés, mais vous pouvez leur transmettre aussi vos propres formulaires.
Django fournit pas de gabarit par défaut pour les vues d’authentification. Vous devez créer vos propres gabarits pour les vues que vous souhaitez utiliser. Le contexte de gabarit est documenté dans chaque vue, voir Toutes les vues d’authentification.
Utilisation des vues¶
Il existe différentes méthodes pour mettre en œuvre ces vues dans votre projet. Le plus simple est d’inclure l’URLconf de django.contrib.auth.urls
dans votre propre URLconf, par exemple
urlpatterns = [
path('accounts/', include('django.contrib.auth.urls')),
]
Cela comprendra les modèles d’URL suivants
accounts/login/ [name='login']
accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']
Les vues possèdent un nom d’URL pour les référencer plus facilement. Voir la documentation des URL pour plus de détails sur l’utilisation de modèles d’URL nommés.
Si vous voulez plus de contrôle sur vos URL, vous pouvez référencer une vue spécifique dans votre URLconf
from django.contrib.auth import views as auth_views
urlpatterns = [
path('change-password/', auth_views.PasswordChangeView.as_view()),
]
Les vues ont des paramètres optionnels que vous pouvez utiliser pour modifier le comportement de la vue. Par exemple, si vous voulez changer le nom du modèle utilisé par une vue, vous pouvez fournir le paramètre template_name
. Une façon de le faire est de fournir des paramètres mot-clé dans l’URLconf, ceux-ci seront transmis à la vue. Par exemple
urlpatterns = [
path(
'change-password/',
auth_views.PasswordChangeView.as_view(template_name='change-password.html'),
),
]
Toutes les vues sont basées sur des classes ce qui permet de les personnaliser facilement par héritage.
Toutes les vues d’authentification¶
Ceci est une liste de toutes les vues fournies par django.contrib.auth
. Pour les détails de l’implémentation, voir Utilisation des vues.
-
class
LoginView
¶ Nom d’URL :
login
Consultez la documentation sur les URL pour plus de détails sur l’utilisation des motifs d’URL nommés.
Attributs :
template_name
: le nom d’un gabarit pour afficher le résultat de la vue de connexion d’un utilisateur. Sa valeur par défaut estregistration/login.html
.redirect_field_name
: le nom d’un champGET
contenant l’URL vers laquelle rediriger après la connexion. Sa valeur par défaut estnext
.authentication_form
: un exécutable (typiquement une classe de formulaire) à utiliser pour l’authentification. Sa valeur par défaut estAuthenticationForm
.extra_context
: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.redirect_authenticated_user
: une valeur booléenne indiquant si les utilisateurs authentifiés accédant à la page de connexion sont redirigés comme s’ils venaient de se connecter. La valeur par défaut estFalse
.Avertissement
Si vous activez
redirect_authenticated_user
, d’autres sites Web seront capables de déterminer si leurs visiteurs sont authentifiés sur votre site en faisant des requêtes de redirection vers des fichiers images de votre site. Pour éviter cette divulgation d’information par « empreinte de médias sociaux », servez toutes les images ainsi que la favicon depuis un domaine distinct.L’activation de
redirect_authenticated_user
peut aussi aboutir à une boucle de redirection lorsque le décorateurpermission_required()
est utilisé sans que le paramètreraise_exception
ne soit indiqué.success_url_allowed_hosts
: un ensembleset
d’hôtes, en plus derequest.get_host()
, qui sont sûrs comme cible de redirection après la connexion. L’ensembleset
est vide par défaut.
Voici ce que fait
LoginView
:- Quand elle est appelée par
GET
, elle affiche un formulaire de connexion dont la ciblePOST
envoie vers la même URL. Plus d’infos à ce sujet dans un moment. - Quand elle est appelée par
POST
avec les données d’authentification d’un utilisateur, elle tente de connecter cet utilisateur. Si l’opération réussit, la vue redirige vers l’URL indiquée dansnext
. Sinext
est absent, elle redirige verssettings.LOGIN_REDIRECT_URL
(/accounts/profile/
par défaut). Si la connexion échoue, la vue affiche à nouveau le formulaire de connexion.
Il est de votre devoir de fournir le code HTML du gabarit de connexion, nommé
registration/login.html
par défaut. Ce gabarit reçoit quatre variables de contexte de gabarit :form
: un objetForm
représentant le formulaireAuthenticationForm
.next
: l’URL vers laquelle rediriger après une connexion réussie. Elle peut aussi contenir une chaîne de requête.site
: leSite
actuel, selon le réglageSITE_ID
. Si l’applicationsite
n’est pas installée, il s’agira d’une instance deRequestSite
qui détecte le nom du site et son domaine à partir de l’objetHttpRequest
en cours.site_name
: un alias desite.name
. Si l’applicationsite
n’est pas installée, cette variable contiendra la valeur derequest.META['SERVER_NAME']
. Pour plus d’informations sur les sites, voir L’infrastructure des « sites ».
Si vous préférez ne pas utiliser le gabarit
registration/login.html
, vous pouvez renseigner le paramètretemplate_name
via les paramètres supplémentaires de la méthodeas_view
dans votre configuration d’URL. Par exemple, cette ligne de configuration d’URL force l’utilisation demyapp/login.html
:path('accounts/login/', auth_views.LoginView.as_view(template_name='myapp/login.html')),
Vous pouvez également définir le nom du champ
GET
contenant l’URL vers laquelle rediriger après la connexion en utiliisantredirect_field_name
. Par défaut, ce champ s’appellenext
.Voici un exemple de gabarit
registration/login.html
comme point de départ. Il compte sur la présence d’un gabaritbase.html
qui définit un bloccontent
:{% extends "base.html" %} {% block content %} {% if form.errors %} <p>Your username and password didn't match. Please try again.</p> {% endif %} {% if next %} {% if user.is_authenticated %} <p>Your account doesn't have access to this page. To proceed, please login with an account that has access.</p> {% else %} <p>Please login to see this page.</p> {% endif %} {% endif %} <form method="post" action="{% url 'login' %}"> {% csrf_token %} <table> <tr> <td>{{ form.username.label_tag }}</td> <td>{{ form.username }}</td> </tr> <tr> <td>{{ form.password.label_tag }}</td> <td>{{ form.password }}</td> </tr> </table> <input type="submit" value="login"> <input type="hidden" name="next" value="{{ next }}"> </form> {# Assumes you setup the password_reset view in your URLconf #} <p><a href="{% url 'password_reset' %}">Lost password?</a></p> {% endblock %}
Si vous avez personnalisé l’authentification (voir Personnalisation de l’authentification), il est possible d’utiliser un formulaire d’authentification personnalisé en définissant l’attribut
authentication_form
. La méthode__init__()
de ce formulaire doit accepter un paramètre nommérequest
; le formulaire doit également implémenter une méthodeget_user()
qui renvoie l’objet utilisateur authentifié (cette méthode n’est appelée qu’à la suite d’une validation de formulaire réussie).
-
class
LogoutView
¶ Déconnecte un utilisateur.
Nom d’URL :
logout
Attributs :
next_page
: l’URL vers laquelle rediriger après la déconnexion. La valeur par défaut estsettings.LOGOUT_REDIRECT_URL
.template_name
: le nom complet d’un gabarit à afficher après la déconnexion d’un utilisateur. Sa valeur par défaut estregistration/logged_out.html
.redirect_field_name
: le nom d’un champGET
contenant l’URL vers laquelle rediriger après la déconnexion. Sa valeur par défaut estnext
. Cela surcharge l’URLnext_page
si le paramètreGET
indiqué est renseigné.extra_context
: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.success_url_allowed_hosts
: un ensembleset
d’hôtes, en plus derequest.get_host()
, qui sont sûrs comme cible de redirection après la déconnexion. L’ensemble est vide par défaut.
Contexte de gabarit :
title
: la chaîne « Logged out », traduite.site
: leSite
actuel, selon le réglageSITE_ID
. Si l’applicationsite
n’est pas installée, il s’agira d’une instance deRequestSite
qui détecte le nom du site et son domaine à partir de l’objetHttpRequest
en cours.site_name
: un alias desite.name
. Si l’applicationsite
n’est pas installée, cette variable contiendra la valeur derequest.META['SERVER_NAME']
. Pour plus d’informations sur les sites, voir L’infrastructure des « sites ».
-
logout_then_login
(request, login_url=None)¶ Déconnecte un utilisateur, puis redirige vers la page de connexion.
Nom d’URL : aucune URL par défaut
Paramètres facultatifs :
login_url
: l’URL de la page de connexion vers laquelle rediriger. Si ce paramètre n’est pas renseigné, la valeur par défaut utilisée estsettings.LOGIN_URL
.
-
class
PasswordChangeView
¶ Nom d’URL :
password_change
Permet à un utilisateur de changer son mot de passe.
Attributs :
template_name
: le nom complet d’un gabarit à utiliser pour l’affichage du formulaire de changement de mot de passe. Sa valeur par défaut estregistration/password_change_form.html
si le paramètre n’est pas renseigné.success_url
: l’URL vers laquelle rediriger après un changement de mot de passe réussi. Contient'password_change_done'
par défaut.form_class
: un formulaire de changement de mot de passe personnalisé qui doit accepter un paramètre nomméuser
. Le formulaire est responsable de changer réellement le mot de passe de l’utilisateur. La valeur par défaut estPasswordChangeForm
.extra_context
: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.
Contexte de gabarit :
form
: le formulaire de changement de mot de passe (voirform_class
ci-dessus).
-
class
PasswordChangeDoneView
¶ Nom d’URL :
password_change_done
La page affichée après qu’un utilisateur a changé son mot de passe.
Attributs :
template_name
: le nom complet d’un gabarit à utiliser. Sa valeur par défaut estregistration/password_change_done.html
si le paramètre n’est pas renseigné.extra_context
: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.
-
class
PasswordResetView
¶ Nom d’URL :
password_reset
Permet à un utilisateur de réinitialiser son mot de passe en générant un lien à usage unique permettant la réinitialisation du mot de passe. Ce lien est envoyé à l’adresse électronique enregistrée pour cet utilisateur.
Si l’adresse électronique indiquée n’existe pas dans le système, cette vue n’envoie pas de courriel, mais l’utilisateur ne reçoit pas non plus de message d’erreur, ceci pour empêcher une divulgation d’information à de potentiels attaquants. Si vous souhaitez fournir un message d’erreur dans cette situation, vous pouvez créer une classe héritant de
PasswordResetForm
et employer l’attributform_class
.Note
Soyez conscients que l’envoi d’un courriel prend un peu de temps, ce qui peut vous rendre vulnérable à une attaque temporelle d’énumération d’adresses électroniques en raison de la différence entre la durée d’une requête de réinitialisation quand l’adresse de courriel existe ou quand elle n’existe pas. Pour éviter cet écart temporel, vous pouvez utiliser un module tiers qui autorise l’envoi asynchrone de courriels, comme par exemple django-mailer.
Les utilisateurs possédant un mot de passe inutilisable (voir
set_unusable_password()
) ne sont pas autorisés à demander la réinitialisation de leur mot de passe afin de prévenir une utilisation abusive avec des sources d’authentification externes comme LDAP. Notez qu’ils ne reçoivent pas de message d’erreur car cela indiquerait que leur compte existe bel et bien, mais ils ne reçoivent pas de courriel non plus.Attributs :
template_name
: le nom complet d’un gabarit à utiliser pour l’affichage du formulaire de réinitialisation du mot de passe. Sa valeur par défaut estregistration/password_reset_form.html
si le paramètre n’est pas renseigné.form_class
: formulaire utilisé pour obtenir l’adresse électronique de l’utilisateur pour lequel le mot de passe doit être réinitialisé. La valeur par défaut estPasswordResetForm
.email_template_name
: le nom complet d’un gabarit à utiliser pour produire le courriel contenant le lien de réinitialisation du mot de passe. Sa valeur par défaut estregistration/password_reset_email.html
si le paramètre n’est pas renseigné.subject_template_name
: le nom complet d’un gabarit à utiliser pour le sujet du courriel contenant le lien de réinitialisation du mot de passe. Sa valeur par défaut estregistration/password_reset_subject.txt
si le paramètre n’est pas renseigné.token_generator
: instance de la classe qui vérifie le lien à usage unique. La valeur par défaut estdefault_token_generator
qui est une instance dedjango.contrib.auth.tokens.PasswordResetTokenGenerator
.success_url
: l’URL vers laquelle rediriger après une demande de réinitialisation de mot de passe réussie. Contient'password_reet_done'
par défaut.from_email
: une adresse électronique valide. Par défaut, Django utiliseDEFAULT_FROM_EMAIL
.extra_context
: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.html_email_template_name
: le nom complet d’un gabarit à utiliser pour produire un courriel avec plusieurs parties text/html et contenant le lien de réinitialisation du mot de passe. Par défaut, le courriel n’est pas envoyé au format HTML.extra_email_context
: un dictionnaire de données de contexte qui sera disponible dans le gabarit du courriel. Il peut être utilisé pour surcharger les valeurs de contexte de gabarit par défaut énumérées ci-dessous, par ex.domain
.
Contexte de gabarit :
form
: le formulaire de réinitialisation du mot de passe de l’utilisateur (voirform_class
ci-dessus).
Contexte de gabarit du courriel :
email
: un alias deuser.email
user
: l’utilisateurUser
actuel, en accord avec le champ de formulaireemail
. Seuls les utilisateurs actifs ont la possibilité de réinitialiser leur mot de passe (User.is_active is True
).site_name
: un alias desite.name
. Si l’applicationsite
n’est pas installée, cette variable contiendra la valeur derequest.META['SERVER_NAME']
. Pour plus d’informations sur les sites, voir L’infrastructure des « sites ».domain
: un alias desite.domain
. Si l’applicationsite
n’est pas installée, cette variable contiendra la valeur derequest.get_host()
.protocol
: http ou httpsuid
: la clé primaire de l’utilisateur codée en base64.token
: jeton servant à contrôler la validité du lien de réinitialisation.
Exemple de
registration/password_reset_email.html
(gabarit de corps de message) :Someone asked for password reset for email {{ email }}. Follow the link below: {{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
Le gabarit du sujet reçoit le même contexte de gabarit. Le sujet doit être une seule ligne de texte brut.
-
class
PasswordResetDoneView
¶ Nom d’URL :
password_reset_done
La page affichée après qu’un utilisateur a reçu le lien pour réinitialiser son mot de passe. Cette vue est appelée par défaut si la vue
PasswordResetView
ne possède pas une URLsuccess_url
définie explicitement.Note
Si l’adresse électronique fournie n’existe pas dans le système, si l’utilisateur est inactif ou si son mot de passe est inutilisable, cette vue sera tout de même affichée, mais aucun message ne sera envoyé.
Attributs :
template_name
: le nom complet d’un gabarit à utiliser. Sa valeur par défaut estregistration/password_reset_done.html
si le paramètre n’est pas renseigné.extra_context
: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.
-
class
PasswordResetConfirmView
¶ Nom d’URL :
password_reset_confirm
Affiche un formulaire pour saisir un nouveau mot de passe.
Paramètres nommés provenant de l’URL :
uidb64
: l’identifiant de l’utilisateur codé en base 64.token
: jeton servant à contrôler la validité du mot de passe.
Attributs :
template_name
: le nom complet d’un gabarit à utiliser pour l’affichage de la vue de confirmation du mot de passe. Sa valeur par défaut estregistration/password_reset_confirm.html
.token_generator
: instance de la classe qui vérifie le mot de passe. La valeur par défaut estdefault_token_generator
qui est une instance dedjango.contrib.auth.tokens.PasswordResetTokenGenerator
.post_reset_login
: une valeur booléenne indiquant si l’utilisateur doit être automatiquement authentifié à la suite d’une réinitialisation de mot de passe réussie. VautFalse
par défaut.post_reset_login_backend
: un chemin Python vers le moteur d’authentification à utiliser lors d’une authentification sipost_reset_login
vautTrue
. Obligatoire seulement si plusieurs moteurs sont configurés dansAUTHENTICATION_BACKENDS
. La valeur par défaut estNone
.form_class
: formulaire utilisé pour définir le mot de passe. La valeur par défaut estSetPasswordForm
.success_url
: l’URL vers laquelle rediriger après une réinitialisation de mot de passe. Contient'password_reset_complete'
par défaut.extra_context
: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.reset_url_token
: paramètre jeton affiché comme composant des URL de réinitialisation de mot de passe. Contient'set-password'
par défaut.
Contexte de gabarit :
form
: le formulaire de définition du mot de passe du nouvel utilisateur (voirform_class
ci-dessus).validlink
: valeur booléenne,True
si le lien (combinaison deuidb64
et detoken
) est valable ou pas encore utilisé.
-
class
PasswordResetCompleteView
¶ Nom d’URL :
password_reset_complete
Affiche une vue informant l’utilisateur que son mot de passe a été changé avec succès.
Attributs :
template_name
: le nom complet d’un gabarit pour afficher la vue. Sa valeur par défaut estregistration/password_reset_complete.html
.extra_context
: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.
Fonctions utilitaires¶
-
redirect_to_login
(next, login_url=None, redirect_field_name='next')¶ Redirige vers la page de connexion, puis vers une autre URL si la connexion réussit.
Paramètres obligatoires :
next_page
: l’URL vers laquelle rediriger après une connexion réussie.
Paramètres facultatifs :
login_url
: l’URL de la page de connexion vers laquelle rediriger. Si ce paramètre n’est pas renseigné, la valeur par défaut utilisée estsettings.LOGIN_URL
.redirect_field_name
: le nom d’un champGET
contenant l’URL vers laquelle rediriger après la déconnexion. Cela surchargenext
si le paramètreGET
indiqué est renseigné.
Formulaires intégrés¶
Si vous ne souhaitez pas utiliser les vues intégrées mais que vous voulez profiter de ne pas devoir réécrire les formulaires de cette fonctionnalité, le système d’authentification fournit plusieurs formulaires intégrés se trouvant dans django.contrib.auth.forms
:
Note
Les formulaires d’authentification intégrés comptent sur un certain nombre de caractéristiques du modèle utilisateur avec lequel ils interagissent. Si vous utilisez un modèle d’utilisateur personnalisé, il peut être nécessaire de définir vos propres formulaires pour le système d’authentification. Pour plus d’informations, consultez la documentation sur l”utilisation des formulaires d’authentification intégrés avec les modèles d’utilisateur personnalisés.
-
class
AdminPasswordChangeForm
¶ Un formulaire utilisé dans l’interface d’administration pour changer le mot de passe d’un utilisateur.
Accepte
user
comme premier paramètre positionnel.
-
class
AuthenticationForm
¶ Un formulaire pour connecter un utilisateur.
Accepte
request
comme premier paramètre positionnel, qui est ensuite stocké dans l’instance de formulaire à disposition des sous-classes.-
confirm_login_allowed
(user)¶ Par défaut,
AuthenticationForm
rejette les utilisateurs pour lesquelsis_active
est àFalse
. Vous pouvez modifier ce comportement pour définir une stratégie personnalisée de détermination des utilisateurs qui peuvent se connecter. Pour cela, utilisez un formulaire personnalisé qui hérite deAuthenticationForm
et remplace la méthodeconfirm_login_allowed()
. Cette méthode doit générer une exceptionValidationError
lorsque l’utilisateur donné n’est pas autorisé à se connecter.Par exemple, pour permettre à tous les utilisateurs de se connecter, indépendamment de leur statut « actif » :
from django.contrib.auth.forms import AuthenticationForm class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm): def confirm_login_allowed(self, user): pass
(Dans ce cas, il faudra aussi utiliser un moteur d’authentification qui autorise les utilisateurs inactifs, tel que
AllowAllUsersModelBackend
.)Ou pour autoriser uniquement certains utilisateurs actifs à se connecter :
class PickyAuthenticationForm(AuthenticationForm): def confirm_login_allowed(self, user): if not user.is_active: raise ValidationError( _("This account is inactive."), code='inactive', ) if user.username.startswith('b'): raise ValidationError( _("Sorry, accounts starting with 'b' aren't welcome here."), code='no_b_users', )
-
-
class
PasswordChangeForm
¶ Un formulaire pour permettre à un utilisateur de changer son mot de passe.
-
class
PasswordResetForm
¶ Un formulaire pour générer et envoyer par courriel un lien à usage unique pour réinitialiser le mot de passe d’un utilisateur.
-
send_mail
(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)¶ Utilise les paramètres pour envoyer un message
EmailMultiAlternatives
. Peut être surchargé pour personnaliser la manière dont le courriel est envoyé à l’utilisateur.Paramètres: - subject_template_name – le gabarit pour le sujet du message.
- email_template_name – le gabarit pour le corps du message.
- context – contexte transmis aux gabarits
subject_template
,email_template
ethtml_email_template
(s’il ne vaut pasNone
). - from_email – l’adresse électronique de l’expéditeur.
- to_email – l’adresse électronique du destinataire.
- html_email_template_name – le gabarit du corps du message HTML ; vaut
None
par défaut, auquel cas un courriel en texte pur est envoyé.
Par défaut,
save()
remplit lecontext
avec les mêmes variables quePasswordResetView
transmet à son contexte d’envoi de courriel.
-
-
class
SetPasswordForm
¶ Un formulaire permettant à un utilisateur de changer son mot de passe sans saisir l’ancien mot de passe.
-
class
UserChangeForm
¶ Un formulaire utilisé dans l’interface d’administration pour modifier les données d’un utilisateur et ses permissions.
-
class
UserCreationForm
¶ Un
ModelForm
pour créer un nouvel utilisateur.Il possède trois champs :
username
(du modèle utilisateur),password1
etpassword2
. Il vérifie quepassword1
etpassword2
correspondent, valide le mot de passe en utilisantvalidate_password()
et définit le mot de passe de l’utilisateur avecset_password()
.
Données d’authentification dans les gabarits¶
L’utilisateur actuellement connecté et ses permissions sont disponibles dans le contexte de gabarit lorsque vous utilisez RequestContext
.
Détail technique
Techniquement, ces variables ne sont disponibles dans le contexte de gabarit que si vous utilisez RequestContext
et que le processeur de contexte "django.contrib.auth.context_processors.auth"
est activé. C’est le cas dans le fichier de réglages par défaut. Pour plus de détails, lisez la documentation de RequestContext.
Utilisateurs¶
Lors de la génération d’un RequestContext
de gabarit, l’utilisateur actuellement connecté, une instance de User
ou de AnonymousUser
, est stockée dans la variable de gabarit {{ user }}
:
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
Cette variable de contexte de gabarit n’est pas disponible si RequestContext
n’est pas utilisé.
Permissions¶
Les permissions de l’utilisateur actuellement connecté sont stockés dans la variable de gabarit {{ perms }}
. C’est une instance de django.contrib.auth.context_processors.PermWrapper
, un objet mandataire de permissions adapté aux gabarits.
La consultation d’attributs simples de {{ perms }}
sous forme de booléen est une méthode mandataire de User.has_module_perms()
. Par exemple, pour vérifier si l’utilisateur connecté a au moins une permission dans l’application foo
:
{% if perms.foo %}
La consultation d’attributs à deux niveaux de {{ perms }}
sous forme de booléen est une méthode mandataire de User.has_perm()
. Par exemple, pour vérifier si l’utilisateur connecté a la permission foo.add_vote
:
{% if perms.foo.add_vote %}
Voici un exemple plus complet de contrôle de permissions dans un gabarit
{% if perms.foo %}
<p>You have permission to do something in the foo app.</p>
{% if perms.foo.add_vote %}
<p>You can vote!</p>
{% endif %}
{% if perms.foo.add_driving %}
<p>You can drive!</p>
{% endif %}
{% else %}
<p>You don't have permission to do anything in the foo app.</p>
{% endif %}
Il est aussi possible de consulter les permissions par des instructions {% if in %}
. Par exemple :
{% if 'foo' in perms %}
{% if 'foo.add_vote' in perms %}
<p>In lookup works, too.</p>
{% endif %}
{% endif %}
Gestion des utilisateurs dans le site d’administration¶
Quand django.contrib.admin
et django.contrib.auth
sont les deux installés, le site d’administration offre une interface pratique pour afficher et gérer les utilisateurs, les groupes et les permissions. Les utilisateurs peuvent être créés et supprimés comme tout autre modèle Django. Des groupes peuvent être créés et des permissions peuvent être attribuées aux utilisateurs et aux groupes. Les modifications de modèles effectuées dans l’administration par les utilisateurs sont également journalisées et affichées.
Création d’utilisateurs¶
Vous devriez voir un lien vers « Utilisateurs » dans la section « Auth » de la page d’accueil du site d’administration. La page d’administration « Ajouter un utilisateur » est différente des autres pages d’administration dans la mesure où elle exige que vous saisissiez d’abord un nom d’utilisateur et un mot de passe avant de pouvoir modifier les autres champs de l’utilisateur.
Notez également que si vous voulez qu’un utilisateur puisse créer d’autres utilisateurs dans le site d’administration de Django, vous devez lui attribuer la permission d’ajouter des utilisateurs et de modifier des utilisateurs (c’est-à-dire les permissions « Can add user » et « Can change user »). Si un compte utilisateur a la permission d’ajouter des utilisateurs mais pas de les modifier, ce compte ne pourra pas créer d’utilisateurs. Pourquoi ? Parce que si vous avez la permission d’ajouter des utilisateurs, vous avez le pouvoir de créer des superutilisateurs, qui peuvent à leur tour modifier d’autres utilisateurs. Django exige donc à la fois les permissions « ajout » et « modification » comme légère mesure de sécurité.
Faites attention à la façon dont vous permettez aux utilisateurs de gérer les autorisations. Si vous donnez à un non-superutilisateur la possibilité d’éditer les utilisateurs, cela revient finalement au même que de lui donner un statut de super-utilisateur, car il sera en mesure d’élever les autorisations des utilisateurs, y compris les siennes !
Modification des mots de passe¶
Les mots de passe des utilisateurs ne sont pas affichés dans le site d’administration (ni stockés dans la base de données), mais les détails de stockage des mots de passe sont visibles. Ces informations contiennent un lien vers le formulaire de changement de mot de passe permettant aux administrateurs de changer les mots de passe des utilisateurs.