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 si SessionAuthenticationMiddleware est activé. Voir Invalidation de session lors du changement de mot de passe pour plus de détails.

Authentification des utilisateurs

authenticate(**credentials)[source]

Pour authentifier un nom d’utilisateur et un mot de passe donnés, utilisez authenticate(). Cette méthode accepte les données d’authentification sous forme de paramètres nommés ; pour la configuration par défaut, il s’agit de username et password, et elle renvoie un objet User si le mot de passe est valable pour le nom d’utilisateur indiqué. Si le mot de passe n’est pas le bon, authenticate() renvoie None. Exemple :

from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    # the password verified for the user
    if user.is_active:
        print("User is valid, active and authenticated")
    else:
        print("The password is valid, but the account has been disabled!")
else:
    # the authentication system was unable to verify the username and password
    print("The username and password were incorrect.")

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 limiter l’accès à des utilisateurs connectés, examinez plutôt le décorateur login_required().

Permissions et autorisations

Django contient un système simple 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 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_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 = [group_list]
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions = [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 trois permissions par défaut (« add », « change » et « delete ») 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')

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.

Mise en cache des permissions

Le moteur ModelBackend met en cache les permissions de l’objet User 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 User à partir de la base de données. Par exemple :

from django.contrib.auth.models import Permission, User
from django.shortcuts import get_object_or_404

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_bar')

    permission = Permission.objects.get(codename='change_bar')
    user.user_permissions.add(permission)

    # Checking the cached permission set
    user.has_perm('myapp.change_bar')  # 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_bar')  # 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)[source]

Pour connecter un utilisateur à partir d’une vue, utilisez login(). Cette fonction accepte un objet HttpRequest et un objet User. 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() et login():

from django.contrib.auth import authenticate, login

def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
            ...
    else:
        # Return an 'invalid login' error message.
        ...

Appel préalable à authenticate()

Lorsque vous connectez un utilisateur manuellement, vous devez authentifier un utilisateur proprement et avec succès avec la fonction authenticate() avant d’appeler login(). authenticate() définit un attribut sur l’objet User indiquant quel moteur d’authentification a servi à authentifier cet utilisateur (voir la documentation sur les moteurs pour plus de détails), cette information étant ensuite nécessaire durant le processus de connexion ultérieur. Une erreur sera générée si vous essayez de connecter un objet utilisateur directement obtenu à partir de la base de données.

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 :

  1. Si le paramètre backend factultatif est fourni, c’est celui-là qui est utilisé.

  2. Si un attribut user.backend existe, c’est celui-là qui est utilisé. Cela permet de combiner authenticate() et login(): authenticate() définit l’attribut user.backend sur l’objet User qu’il renvoie.

  3. S’il n’y a qu’un seul moteur dans AUTHENTICATION_BACKENDS, c’est celui-là qui est utilisé.

  4. 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)[source]

Pour déconnecter un utilisateur qui a été connecté par django.contrib.auth.login(), utilisez django.contrib.auth.logout() depuis la vue. Cette fonction accepte un objet HttpRequest 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 simple et 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)[source]

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 facultatif redirect_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 de redirect_field_name comme clé à la place de "next" (la valeur par défaut).

login_required() accepte également un paramètre facultatif login_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églage settings.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

url(r'^accounts/login/$', auth_views.login),

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.

Note

Le décorateur login_required ne vérifie PAS le drapeau is_active d’un utilisateur.

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
New in Django 1.9.

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.

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.

La manière simple est d’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')[source]

Comme raccourci, vous pouvez utiliser le décorateur user_passes_test qui procède à une redirection lorsque la fonction décorée renvoie False:

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 objet User et renvoyant True si l’utilisateur est autorisé à voir la page. Notez que user_passes_test() ne contrôle pas d’office que l’objet User 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
New in Django 1.9.

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 de AccessMixin 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 de test_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 appelait super() 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)[source]

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.can_vote')
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.can_vote pour une permission d’un modèle de l’application polls).

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 facultatif login_url:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote', login_url='/loginpage/')
def my_view(request):
    ...

Comme pour le décorateur login_required(), la valeur par défaut de login_url est settings.LOGIN_URL.

Si le paramètre raise_exception est présent, le décorateur génère une exception PermissionDenied (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écorateur login_required():

from django.contrib.auth.decorators import login_required, permission_required

@login_required
@permission_required('polls.can_vote', raise_exception=True)
def my_view(request):
    ...
Changed in Django 1.9:

Dans les anciennes versions, le paramètre permission ne fonctionnait qu’avec des chaînes, des listes et des tuples au lieu de chaînes et de n’importe quelle itération.

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
New in Django 1.9.

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ètre permission_required:

from django.contrib.auth.mixins import PermissionRequiredMixin

class MyView(PermissionRequiredMixin, View):
    permission_required = 'polls.can_vote'
    # Or multiple of permissions:
    permission_required = ('polls.can_open', 'polls.can_edit')

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 par get_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 rediriger un utilisateur vers la page de connexion ou générer une réponse d’accès interdit (HTTP 403 Forbidden).

class AccessMixin
New in Django 1.9.
login_url

Valeur de renvoi par défaut de get_login_url(). Contient None par défaut auquel cas get_login_url() se rabat sur le contenu de settings.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 exception PermissionDenied sera produite à la place d’une redirection. La valeur par défaut est False.

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, sinon settings.LOGIN_URL.

get_permission_denied_message()

Lorsque raise_exception vaut True, 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’attribut permission_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’attribut redirect_field_name.

handle_no_permission()

En fonction de la valeur de raise_exception, cette méthode peut soit générer une exception PermissionDenied, soit rediriger l’utilisateur vers login_url, incluant potentiellement redirect_field_name si celui-ci est défini.

Invalidation de session lors du changement de mot de passe

Avertissement

Cette protection ne s’applique que si SessionAuthenticationMiddleware est activé dans MIDDLEWARE_CLASSES. Il est inclus si settings.py a été généré par startproject avec Django ≥ 1.7.

La vérification des sessions deviendra obligatoire dans Django 1.10, sans tenir compte de la présence active de SessionAuthenticationMiddleware. Si vous avez un projet datant d’avant 1.7 ou qui a été généré à l’aide d’un gabarit n’incluant pas SessionAuthenticationMiddleware, vous devriez envisager de l’activer dès maintenant après avoir lu les indications de mise à jour ci-dessous.

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. Si l’intergiciel SessionAuthenticationMiddleware est activé, Django vérifie que la valeur de hachage envoyée avec chaque requête correspond à celle qui est calculée côté serveur. 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, django.contrib.auth.views.password_change() 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 cette fonction :

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. 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:
        ...

Si vous mettez à jour un site existant et que vous souhaitez activer cet intergiciel sans provoquer ensuite une reconnexion de tous les utilisateurs, vous devez d’abord mettre à niveau vers Django 1.7 et faire fonctionner le site pendant un certain temps pour que les sessions soient naturellement recréées au fur et à mesure que les utilisateurs se connectent, et qu’elles comprennent le hachage de la session, comme décrit ci-dessus. Une fois que le site commence à fonctionner avec SessionAuthenticationMiddleware, tout utilisateur ne s’étant pas connecté et dont la session n’aura donc pas été mise à jour avec le hachage de vérification devra se ré-identifier, car sa session existante aura été invalidée.

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 = [
    url('^', include('django.contrib.auth.urls')),
]

Cela comprendra les modèles d’URL suivants

^login/$ [name='login']
^logout/$ [name='logout']
^password_change/$ [name='password_change']
^password_change/done/$ [name='password_change_done']
^password_reset/$ [name='password_reset']
^password_reset/done/$ [name='password_reset_done']
^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
^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 = [
    url('^change-password/$', auth_views.password_change),
]

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 = [
    url(
        '^change-password/$',
        auth_views.password_change,
        {'template_name': 'change-password.html'}
    ),
]

Toutes les vues renvoient une instance de TemplateResponse, qui vous permet de personnaliser facilement les données de réponse avant le rendu. Une façon de le faire est d’envelopper une vue dans votre propre vue

from django.contrib.auth import views

def change_password(request):
    template_response = views.password_change(request)
    # Do something with `template_response`
    return template_response

Pour plus de détails, consultez la documentation de TemplateResponse.

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.

login(request, template_name=`registration/login.html`, redirect_field_name='next', authentication_form=AuthenticationForm, current_app=None, extra_context=None)

Nom d’URL : login

Consultez la documentation sur les URL pour plus de détails sur l’utilisation des motifs d’URL nommés.

Paramètres facultatifs :

  • 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 est registration/login.html.

  • redirect_field_name: le nom d’un champ GET contenant l’URL vers laquelle rediriger après la connexion. Sa valeur par défaut est next.

  • authentication_form: un exécutable (typiquement une simple classe de formulaire) à utiliser pour l’authentification. Sa valeur par défaut est AuthenticationForm.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • extra_context: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

Voici ce que fait django.contrib.auth.views.login:

  • Quand elle est appelée par GET, elle affiche un formulaire de connexion dont la cible POST 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 dans next. Si next est absent, elle redirige vers settings.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 objet Form représentant le formulaire AuthenticationForm.

  • next: l’URL vers laquelle rediriger après une connexion réussie. Elle peut aussi contenir une chaîne de requête.

  • site: le Site actuel, selon le réglage SITE_ID. Si l’application site n’est pas installée, il s’agira d’une instance de RequestSite qui détecte le nom du site et son domaine à partir de l’objet HttpRequest en cours.

  • site_name: un alias de site.name. Si l’application site n’est pas installée, cette variable contiendra la valeur de request.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ètre template_name via les paramètres supplémentaires de vue dans votre configuration d’URL. Par exemple, cette ligne de configuration d’URL force l’utilisation de myapp/login.html:

url(r'^accounts/login/$', auth_views.login, {'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 passant redirect_field_name à la vue. Par défaut, ce champ s’appelle next.

Voici un exemple de gabarit registration/login.html comme point de départ. Il compte sur la présence d’un gabarit base.html qui définit un bloc content:

{% 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 de transmettre un formulaire d’authentification personnalisé à la vue de connexion par le paramètre authentication_form. La méthode __init__ de ce formulaire doit accepter un paramètre nommé request; le formulaire doit également implémenter une méthode get_user() qui renvoie l’objet utilisateur authentifié (cette méthode n’est appelée qu’à la suite d’une validation de formulaire réussie).

logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name='next', current_app=None, extra_context=None)

Déconnecte un utilisateur.

Nom d’URL : logout

Paramètres facultatifs :

  • next_page: l’URL vers laquelle rediriger après la déconnexion.

  • template_name: le nom complet d’un gabarit à afficher après la déconnexion d’un utilisateur. Sa valeur par défaut est registration/logged_out.html si le paramètre n’est pas renseigné.

  • redirect_field_name: le nom d’un champ GET contenant l’URL vers laquelle rediriger après la déconnexion. Sa valeur par défaut est next. Cela surcharge l’URL next_page si le paramètre GET indiqué est renseigné.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • extra_context: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

Contexte de gabarit :

  • title: la chaîne « Logged out », traduite.

  • site: le Site actuel, selon le réglage SITE_ID. Si l’application site n’est pas installée, il s’agira d’une instance de RequestSite qui détecte le nom du site et son domaine à partir de l’objet HttpRequest en cours.

  • site_name: un alias de site.name. Si l’application site n’est pas installée, cette variable contiendra la valeur de request.META['SERVER_NAME']. Pour plus d’informations sur les sites, voir L’infrastructure des « sites ».

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • extra_context: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.

logout_then_login(request, login_url=None, current_app=None, extra_context=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 est settings.LOGIN_URL.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • extra_context: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

password_change(request, template_name='registration/password_change_form.html', post_change_redirect=None, password_change_form=PasswordChangeForm, current_app=None, extra_context=None)

Permet à un utilisateur de changer son mot de passe.

Nom d’URL : password_change

Paramètres facultatifs :

  • 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 est registration/password_change_form.html si le paramètre n’est pas renseigné.

  • post_change_redirect: l’URL vers laquelle rediriger après un changement de mot de passe réussi.

  • password_change_form: 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 est PasswordChangeForm.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • extra_context: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

Contexte de gabarit :

  • form: le formulaire de changement de mot de passe (voir password_change_form ci-dessus).

password_change_done(request, template_name='registration/password_change_done.html', current_app=None, extra_context=None)

La page affichée après qu’un utilisateur a changé son mot de passe.

Nom d’URL : password_change_done

Paramètres facultatifs :

  • template_name: le nom complet d’un gabarit à utiliser. Sa valeur par défaut est registration/password_change_done.html si le paramètre n’est pas renseigné.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • extra_context: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None, extra_email_context=None)

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 le paramètre password_reset_form.

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.

Nom d’URL : password_reset

Paramètres facultatifs :

  • 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 est registration/password_reset_form.html si le paramètre n’est pas renseigné.

  • 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 est registration/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 est registration/password_reset_subject.txt si le paramètre n’est pas renseigné.

  • password_reset_form: 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 est PasswordResetForm.

  • token_generator: instance de la classe qui vérifie le lien à usage unique. La valeur par défaut est default_token_generator qui est une instance de django.contrib.auth.tokens.PasswordResetTokenGenerator.

  • post_change_redirect: l’URL vers laquelle rediriger après une demande de réinitialisation de mot de passe réussie.

  • from_email: une adresse électronique valide. Par défaut, Django utilise DEFAULT_FROM_EMAIL.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • 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.

Obsolète depuis la version 1.8: Le paramètre is_admin_site est obsolète et sera supprimé dans Django 1.10.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

New in Django 1.9:

Le paramètre extra_email_context a été ajouté.

Contexte de gabarit :

  • form: le formulaire de réinitialisation du mot de passe de l’utilisateur (voir password_reset_form ci-dessus).

Contexte de gabarit du courriel :

  • email: un alias de user.email

  • user: l’utilisateur User actuel, en accord avec le champ de formulaire email. Seuls les utilisateurs actifs ont la possibilité de réinitialiser leur mot de passe (User.is_active is True).

  • site_name: un alias de site.name. Si l’application site n’est pas installée, cette variable contiendra la valeur de request.META['SERVER_NAME']. Pour plus d’informations sur les sites, voir L’infrastructure des « sites ».

  • domain: un alias de site.domain. Si l’application site n’est pas installée, cette variable contiendra la valeur de request.get_host().

  • protocol: http ou https

  • uid: 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.

password_reset_done(request, template_name='registration/password_reset_done.html', current_app=None, extra_context=None)

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 password_reset() ne possède pas une URL post_reset_redirect définie explicitement.

Nom d’URL : password_reset_done

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é.

Paramètres facultatifs :

  • template_name: le nom complet d’un gabarit à utiliser. Sa valeur par défaut est registration/password_reset_done.html si le paramètre n’est pas renseigné.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • extra_context: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

password_reset_confirm(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None)

Affiche un formulaire pour saisir un nouveau mot de passe.

Nom d’URL : password_reset_confirm

Paramètres facultatifs :

  • uidb64: l’identifiant de l’utilisateur codé en base64. None par défaut.

  • token: jeton servant à contrôler la validité du mot de passe. None par défaut.

  • 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 est registration/password_reset_confirm.html.

  • token_generator: instance de la classe qui vérifie le mot de passe. La valeur par défaut est default_token_generator qui est une instance de django.contrib.auth.tokens.PasswordResetTokenGenerator.

  • set_password_form: formulaire utilisé pour définir le mot de passe. La valeur par défaut est SetPasswordForm.

  • post_reset_redirect: l’URL vers laquelle rediriger après une réinitialisation de mot de passe. None par défaut.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • 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 du mot de passe de l’utilisateur (voir set_password_form ci-dessus).

  • validlink: valeur booléenne, True si le lien (combinaison de uidb64 et de token) est valable ou pas encore utilisé.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

password_reset_complete(request, template_name='registration/password_reset_complete.html', current_app=None, extra_context=None)

Affiche une vue informant l’utilisateur que son mot de passe a été changé avec succès.

Nom d’URL : password_reset_complete

Paramètres facultatifs :

  • template_name: le nom complet d’un gabarit pour afficher la vue. Sa valeur par défaut est registration/password_reset_complete.html.

  • current_app: une indication de l’application contenant la vue actuelle. Consultez la stratégie de résolution des URL en espaces de noms pour plus d’informations.

  • extra_context: un dictionnaire de données de contexte qui sera fusionné avec les données de contexte par défaut transmises au gabarit.

Obsolète depuis la version 1.9: Le paramètre current_app est obsolète et sera supprimé dans Django 2.0. Le code appelant devrait plutôt définir request.current_app.

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 est settings.LOGIN_URL.

  • redirect_field_name: le nom d’un champ GET contenant l’URL vers laquelle rediriger après la déconnexion. Cela surcharge next si le paramètre GET 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 lesquels is_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 de AuthenticationForm et remplace la méthode confirm_login_allowed(). Cette méthode doit générer une exception ValidationError 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

Ou pour autoriser uniquement certains utilisateurs actifs à se connecter :

class PickyAuthenticationForm(AuthenticationForm):
    def confirm_login_allowed(self, user):
        if not user.is_active:
            raise forms.ValidationError(
                _("This account is inactive."),
                code='inactive',
            )
        if user.username.startswith('b'):
            raise forms.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_email(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)
New in Django 1.8.

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 et html_email_template (s’il ne vaut pas None).
  • 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 le context avec les mêmes variables que password_reset() 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 formulaire pour créer un nouvel utilisateur.

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.

Dans l’objet {{ perms }}, la consultation d’attributs simples est une méthode mandataire de User.has_module_perms. Cet exemple affiche True si l’utilisateur connecté a au moins une permission dans l’application foo:

{{ perms.foo }}

La consultation d’attributs à deux niveaux est une méthode mandataire de User.has_perm. Cet exemple affiche True si l’utilisateur connecté a la permission foo.can_vote:

{{ perms.foo.can_vote }}

Vous pouvez donc vérifier les permissions dans des instructions {% if %} de gabarits :

{% if perms.foo %}
    <p>You have permission to do something in the foo app.</p>
    {% if perms.foo.can_vote %}
        <p>You can vote!</p>
    {% endif %}
    {% if perms.foo.can_drive %}
        <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.can_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.

Back to Top