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, étant capable de gérer une large palette de tâches ; elle possède une implémentation soigneuse des mots de passe et des permissions, convenant à de nombreux projets sans besoin de modification. 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.

Django authentication provides both authentication and authorization together and is generally referred to as the authentication system, as these features are somewhat coupled.

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 « superutilisateurs » ou les membres des équipes d’administration du site 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 :

  • nom d’utilisateur

  • mot de passe

  • adresse électronique

  • prénom

  • nom

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

manage.py syncdb vous demande de créer un superutilisateur la première fois que vous la lancez, pour autant que 'django.contrib.auth' figure dans le réglage INSTALLED_APPS. Si vous avez besoin de créer un superutilisateur plus tard, vous pouvez utiliser un utilitaire en ligne de commande :

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__exact='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.

Authentification des utilisateurs

authenticate(**credentials)

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.")

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 syncdb; la première fois que vous lancez syncdb 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 syncdb crée les permissions par défaut pour les nouveaux modèles.

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 Group, 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.

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()

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.

Calling authenticate() first

When you’re manually logging a user in, you must call authenticate() before you call login(). authenticate() sets an attribute on the User noting which authentication backend successfully authenticated that user (see the backends documentation for details), and this information is needed later during the login process. An error will be raised if you try to login a user object retrieved from the database directly.

Déconnexion d’un utilisateur

logout()

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.shortcuts import redirect

def my_view(request):
    if not request.user.is_authenticated():
        return redirect('/login/?next=%s' % 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=REDIRECT_FIELD_NAME, 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 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 la ligne suivante dans votre configuration d’URL :

(r'^accounts/login/$', 'django.contrib.auth.views.login'),
Changed in Django 1.5.

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.

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 :

def my_view(request):
    if not '@example.com' in request.user.email:
        return HttpResponse("You can't vote in this poll.")
    # ...
user_passes_test(func[, login_url=None])

Comme raccourci, vous pouvez utiliser le décorateur user_passes_test:

from django.contrib.auth.decorators import user_passes_test

def email_check(user):
    return '@example.com' in user.email

@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 un paramètre facultatif login_url qui permet d’indiquer l’URL de la page de connexion (settings.LOGIN_URL par défaut).

Par exemple :

@user_passes_test(email_check, login_url='/login/')
def my_view(request):
    ...

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

Notez que permission_required() accepte également un paramètre facultatif login_url. Exemple :

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.

Changed in Django 1.4.

Le paramètre raise_exception a été ajouté. Quand il 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.

Contrôle de permission sur les vues génériques

Pour vérifier une permission dans le cas des vues génériques basées sur des classes, décorez la méthode View.dispatch de la classe. Voir Decorating the class pour plus de détails.

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 ne fournit pas de gabarit par défaut pour les vues d’authentification, mais le contexte de gabarit est documenté ci-dessous pour chaque vue.

New in Django 1.4.

Les vues intégrées renvoient toutes une instance TemplateResponse, ce qui permet de personnaliser facilement les données de la réponse avant le rendu du gabarit. Pour plus de détails, consultez la documentation de TemplateResponse.

La plupart des vues d’authentification intégrées fournissent un nom d’URL pour s’y référer plus facilement. Consultez la documentation sur les URL pour plus de détails sur l’utilisation des motifs d’URL nommés.

login(request[, template_name, redirect_field_name, authentication_form, current_app, extra_context])

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: The name of a template to display for the view used to log the user in. Defaults to registration/login.html.
  • redirect_field_name: The name of a GET field containing the URL to redirect to after login. Defaults to next.
  • authentication_form: A callable (typically just a form class) to use for authentication. Defaults to AuthenticationForm.
  • current_app: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.

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 le domaine à partir de l’objet HttpRequest.

  • 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 The “sites” framework.

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:

(r'^accounts/login/$', 'django.contrib.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 %}

<form method="post" action="{% url 'django.contrib.auth.views.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>

{% 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, template_name, redirect_field_name, current_app, extra_context])

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: The name of a GET field containing the URL to redirect to after log out. Defaults to next. Overrides the next_page URL if the given GET parameter is passed.
  • current_app: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.

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 le domaine à partir de l’objet HttpRequest.

  • 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 The “sites” framework.

  • current_app: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.
logout_then_login(request[, login_url, current_app, extra_context])

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: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.
password_change(request[, template_name, post_change_redirect, password_change_form, current_app, extra_context])

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: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.

Contexte de gabarit :

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

password_change_done(request[, template_name, current_app, extra_context])

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: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.
password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email, current_app, extra_context])

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.

Changed in Django 1.4: Users flagged with an unusable password (see set_unusable_password() will not be able to request a password reset to prevent misuse when using an external authentication source like LDAP.

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

    New in Django 1.4.
  • 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: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.

  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.

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 The “sites” framework.

  • 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: l’identifiant de l’utilisateur codé en base36.

  • 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' uidb36=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, current_app, extra_context])

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

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: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.
password_reset_confirm(request[, uidb36, token, template_name, token_generator, set_password_form, post_reset_redirect, current_app, extra_context])

Affiche un formulaire pour saisir un nouveau mot de passe.

Nom d’URL : password_reset_confirm

Paramètres facultatifs :

  • uidb36: l’identifiant de l’utilisateur codé en base36. 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_change_redirect: l’URL vers laquelle rediriger après une réinitialisation de mot de passe. None par défaut.

  • current_app: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.

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 uidb36 et du jeton) est valable ou pas encore utilisé.

password_reset_complete(request[, template_name, current_app, extra_context])

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: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
  • extra_context: A dictionary of context data that will be added to the default context data passed to the template.

Fonctions utilitaires

redirect_to_login(next[, login_url, redirect_field_name])

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.

class AuthenticationForm

Un formulaire pour connecter un utilisateur.

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.

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 gabariz lorsque vous utilisez RequestContext.

Technicality

Techniquement, ces variables ne sont disponibles dans le contexte de gabarit que si vous utilisez RequestContext et que votre réglage TEMPLATE_CONTEXT_PROCESSORS contient "django.contrib.auth.context_processors.auth", ce qui est le cas 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 %}
New in Django 1.5: Permission lookup by “if in”.

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

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