• 12 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 22/03/2024

Créez une page de connexion avec une vue basée sur une fonction

Programmez la vue pour que les utilisateurs se connectent

Parfait ! Nous avons maintenant un moyen de stocker différents utilisateurs dans notre base de données. Néanmoins, pour savoir qui sont ces utilisateurs, nous devons leur donner un moyen de se connecter au site.

Découvrons maintenant en vidéo comment construire une vue qui sera notre portail de connexion.

Étape 1 : Créez le LoginForm (formulaire de connexion)

Tout d’abord, créez un fichier  forms.py  qui contiendra le formulaire de connexion.

(ENV) ~/fotoblog (master)
→ touch authentication/forms.py

Dans ce fichier, créez le  LoginForm.

# authentication/forms.py
from django import forms

class LoginForm(forms.Form):
    username = forms.CharField(max_length=63, label='Nom d’utilisateur')
    password = forms.CharField(max_length=63, widget=forms.PasswordInput, label='Mot de passe')

Vous remarquerez aussi que nous paramétrons le champ Mot de passe (« password ») pour qu’il utilise le widget  forms.PasswordInput. Un widget détermine la façon dont vous affichez le champ. Comme vous l’avez peut-être deviné, le widget  PasswordInput  cache automatiquement la saisie en utilisant un  <input>  HTML avec l’attribut  type="password"  .

Étape 2 : Créez la vue de la page de connexion

Maintenant que nous avons notre formulaire de connexion, il est temps de l’inclure dans une vue.

# authentication/views.py
from django.shortcuts import render

from . import forms


def login_page(request):
    form = forms.LoginForm()
    if request.method == 'POST':
        form = forms.LoginForm(request.POST)
        if form.is_valid():
            pass
    return render(request, 'authentication/login.html', context={'form': form})

Super ! Le  LoginForm  est maintenant utilisé dans la vue. Néanmoins, comme vous pouvez le constater, nous ne gérons pas réellement les données  POST  pour l’instant.

Django est fourni avec une série de méthodes qui peuvent aider les développeurs à gagner du temps. Vous pouvez utiliser les fonctions  login  et   authenticate  du module  django.contrib.auth  pour l’authentification.

Voici comment les utiliser dans une vue.

from django.contrib.auth import login, authenticate  # import des fonctions login et authenticate

def login_page(request):
    form = forms.LoginForm()
    message = ''
    if request.method == 'POST':
        form = forms.LoginForm(request.POST)
        if form.is_valid():
            user = authenticate(
                username=form.cleaned_data['username'],
                password=form.cleaned_data['password'],
            )
            if user is not None:
                login(request, user)
                message = f'Bonjour, {user.username}! Vous êtes connecté.'
            else:
                message = 'Identifiants invalides.'
    return render(
        request, 'authentication/login.html', context={'form': form, 'message': message})

Commençons par nous intéresser à la fonction  authenticate. Cette fonction prend deux arguments : le nom d’utilisateur et le mot de passe.

Si les identifiants sont corrects, elle retourne l’utilisateur correspondant aux identifiants. Sinon, elle retourne None.

La fonctionauthenticate   seule ne gère pas la connexion de l’utilisateur. Pour cela, utilisez la fonctionlogin. Elle prend deux arguments : l’objetrequestet l’objetuser  correspondant à l’utilisateur qui doit être connecté.

Et nous y voilà ! Vous avez maintenant une vue qui permet à un utilisateur de se connecter au site.

Étape 3 : Ajoutez un gabarit, ou template

Nous avons spécifié que nous utilisons le gabaritauthentication/login.html  dans la vue  login_page. Créons ce gabarit maintenant !

Premièrement, créez les répertoires qui contiendront les gabarits. Nous en ajouterons un à chacune de nos applications, puis un à la racine du projet.

(ENV) ~/fotoblog (master)
→ mkdir -p  authentication/templates/authentication

(ENV) ~/fotoblog (master)
→ mkdir -p blog/templates/blog/

(ENV) ~/fotoblog (master)
→ mkdir templates

Ensuite, créez les gabarits : commencez par un gabarit de base qui sera utilisé pour l’ensemble du projet, puis celui de la page de connexion.

# templates/base.html
<html>
    <head>
        <title>FotoBlog</title>
    </head>
    <body>
        <h1>FotoBlog</h1>
        {% block content %}{% endblock content %}
    </body>
</html>
# authentication/templates/authentication/login.html
{% extends 'base.html' %}
{% block content %}
    <p>{{ message }}</p>
    <form method="post">
        {{ form.as_p }}
        {% csrf_token %}
        <button type="submit" >Se connecter</button>
    </form>
{% endblock content %}

Si vous avez déjà eu l’occasion de créer une application Django en utilisant l’héritage de gabarit, vous reconnaissez probablement l’expression  {% extends base.html %}  . Vu que nous allons utiliser notre gabarit de base dans différentes applications, nous l’avons placé dans le répertoire des gabarits du projet, et non dans une application.

Lorsque  APP_DIRS  est réglé sur  True, Django trouve automatiquement le répertoire  templates/  quand il est situé dans une application. Néanmoins, comme nous plaçons le gabarit de base à la racine du projet, nous devons le spécifier danssettings.py  pour que Django puisse trouver ce répertoire.

Pour ce faire, modifiez votre fichiersettings.pycomme ceci :

# fotoblog/settings.py
...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            BASE_DIR.joinpath('templates'),  # <--- ajoutez cette ligne
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
...

Ce code dit à Django qu’il y a des gabarits dans le répertoire  templates/  à la racine du projet. Un chemin absolu, c’est-à-dire depuis le répertoire racine, est nécessaire. Utilisez la constante  BASE_DIR  pour permettre cela.

Étape 4 : Ajoutez l’URL à urlpatterns

Le  LoginForm  est construit et incorporé à la vuelogin_page. Vous avez maintenant un gabarit que vous pouvez utiliser pour générer la page HTML.

Vous n’avez plus qu’à inclure le modèle, ou pattern, d’URL dansurls.py   .

from django.contrib import admin
from django.urls import path

import authentication.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', authentication.views.login_page, name='login'),
]

Étape 5 : Affichez la page de connexion

Parfait ! Démarrons le serveur de développement pour voir la nouvelle page de connexion. Voici la procédure en vidéo :

On dirait que la page de connexion s’affiche comme prévu. Il est temps de la tester !

Testez la fonctionnalité de connexion et ajoutez la déconnexion

Plus tard, nous construirons une page d’inscription pour permettre aux utilisateurs de rejoindre le site. Mais pour l’instant, commençons par créer un utilisateur dans le shell Django et utilisons-le pour tester la fonctionnalité de connexion. Voici la technique en vidéo :

Pour ouvrir le shell Django, exécutez  python manage.py shell.

Étape 1 : Créez un utilisateur

Importez votre modèle  User  personnalisé dans le shell Django.

>>> from authentication.models import User
>>> User.objects.create_user(username='toto', password='S3cret!', role='CREATOR')
<User: toto>

Étape 2 : Testez la fonctionnalité de connexion

Maintenant que nous avons un utilisateur stocké dans la base de données, retournons à la page de connexion et essayons de nous connecter.

Capture d’écran d’une connexion réussie
Capture d’écran d’une connexion réussie

Super, ça a marché ! Réessayons avec un mauvais mot de passe !

Capture d’écran d’une connexion qui a échoué
Capture d’écran d’une connexion qui a échoué

Parfait !

Étape 3 : Créez une vue de déconnexion

Maintenant que vous pouvez vous connecter, il serait logique que vous puissiez aussi vous déconnecter. Comment faire ? La réponse en vidéo :

Ajoutons une vue de déconnexion.

# authentication/views.py
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import redirect, render

from . import forms

def logout_user(request):
    
    logout(request)
    return redirect('login')
    
def login_page(request):
    ...

Pour cela, vous allez utiliser une autre fonction —  logout  — de  django.contrib.auth .

La vue dit à Django de déconnecter l’utilisateur. Vous utilisez ensuite la fonction redirect  pour rediriger l’utilisateur vers la page de connexion. La fonction  redirect  peut prendre un nom de vue, comme spécifié dans  urls.py   .

Étape 4 : Ajouter la vue de déconnexion aux modèles d’URL

Et maintenant, ajoutons une nouvelle entrée aux modèles d’URL.

# authentication/urls.py
urlpatterns = [
    ...
    path('logout/', authentication.views.logout_user, name='logout'),
]

Étape 5 : Ajoutez le gabarit de déconnexion

Pour finir, ajoutez un lien vers la page de déconnexion dans  base.html. Ainsi, il est visible dès qu’un utilisateur est connecté, du moment que vous étendez  base.html  .

# templates/base.html
<html>
    <head>
        <title>FotoBlog</title>
    </head>
    <body>
        <h1>FotoBlog</h1>
        {% block content %}{% endblock content %}
        {%  if user.is_authenticated %}
            <p>Vous êtes connecté en tant que {{ request.user }}. <a href="{% url 'logout' %}">Se déconnecter</a></p>
        {% endif %}
    </body>
</html>

Vous pouvez toujours accéder à l’objet  user  dans le gabarit. Il correspond à l’utilisateur  qui est en train de naviguer sur le site. Il est important de noter que Django représente un utilisateur anonyme avec un objet de type  AnonymousUser.  Par conséquent, la seule présence d’un objet  user  ne suffit pas à nous indiquer si l’utilisateur est authentifié.

Pour le vérifier, vous devez utiliser la méthode  user.is_authenticated  . Elle renvoie  True   si l’utilisateur est authentifié, ou  False  dans le cas contraire.

Et maintenant, essayez les fonctionnalités de connexion et de déconnexion.

Restreignez l’accès à une partie du site aux utilisateurs connectés uniquement

Maintenant que vous pouvez connecter et déconnecter des utilisateurs, créons une page d’accueil vers laquelle rediriger les utilisateurs une fois connectés. Comme cette page ne s’occupe pas de l’authentification, vous allez la créer dans l’application  blog. La procédure en vidéo ci-dessous :

Étape 1 : Ajoutez la vue

Commençons par une vue :

# blog/views.py
def home(request):
    return render(request, 'blog/home.html')

Étape 2 : Ajoutez un gabarit

Puis un gabarit :

# blog/templates/blog/home.html
{% extends 'base.html' %}
{% block content %}
    <p>Vous êtes connecté !</p>
{% endblock content %}

Étape 3 : Ajoutez le modèle d’URL

Ajoutez un modèle d’URL dans urls.py :

# urls.py
import blog.views

urlpatterns = [
    ...
    path('home/', blog.views.home, name='home'),
]

Étape 4 : Configurez une redirection après connexion

Vous devez maintenant dire à Django de rediriger vers cette page après une connexion réussie.

# views.py
def login_page(request):
    form = forms.LoginForm()
    message = ''
    if request.method == 'POST':
        form = forms.LoginForm(request.POST)
        if form.is_valid():
            user = authenticate(
                username=form.cleaned_data['username'],
                password=form.cleaned_data['password'],
            )
            if user is not None:
                login(request, user)
                return redirect('home')
        message = 'Identifiants invalides.'
    return render(request, 'authentication/login.html', context={'form': form, 'message': message})

Étape 5 : Testez la connexion

Voyons ce qu’il se passe lorsque nous nous connectons.

Capture d’écran d’une page après connexion

Capture d’écran d’une connexion réussie
Capture d’écran d’une connexion réussie

Joli, mais qu’est-ce qu’il se passerait si je me déconnectais et que j’essayais d’accéder à cette page directement par le biais de l’URL ?

Capture d’écran d’une connexion réussie
Capture d’écran d’une connexion réussie

Ça, ce n’est pas censé arriver !

Il vous faut un moyen de restreindre l’accès à des pages pour que seuls les utilisateurs connectés puissent y accéder. Heureusement, Django fournit le décorateur  login_required  , qui remplit exactement ce rôle.

Étape 6 : Restreignez l’accès à la page d’accueil

Utilisons le décorateur  login_required   sur la vue  home  en ajoutant les lignes suivantes au fichier  blog/views.html.

# blog/views.py
from django.contrib.auth.decorators import login_required


@login_required
def home(request):
    return render(request, blog/home.html')

Pour que ça fonctionne, vous devez dire à Django vers quelle page rediriger si l’utilisateur n’est pas connecté. Faites-le en configurant  LOGIN_URL  avec l’URL de la page de connexion ou, encore mieux, avec le nom du modèle d’URL de la page de connexion (login) dans  settings.py  .

# fotoblog/settings.py

LOGIN_URL = 'login'

Essayez à nouveau d’accéder à la page d’accueil sans être connecté. Vous allez voir que vous êtes maintenant redirigé vers la page de connexion.

En résumé 

  • Vous pouvez utiliser la fonction  authenticate   pour vérifier les identifiants d’un utilisateur, et la méthode  login  pour le connecter. Utilisez la méthode   logout   pour le déconnecter.

  • La méthodeuser.is_authenticatedvérifie si l’utilisateur actuel est connecté.

  • Vous pouvez utiliser le décorateur login_required  sur une vue pour restreindre l’accès à certaines parties du site aux utilisateurs connectés uniquement.

Maintenant que nous avons construit un système de connexion qui utilise des vues basées sur des fonctions, voyons comment nous servir du pouvoir des vues basées sur des classes pour rendre les choses encore plus faciles.

Exemple de certificat de réussite
Exemple de certificat de réussite