Découvrez comment vous pouvez construire un système d’authentification simple (s’inscrire, connecter et déconnexer) en utilisant le cadre Django et Bootstrap en Python.
De nombreux sites en ligne ne peuvent être consultés que si nous nous enregistrons dans leurs systèmes. Heureusement, Django peut nous permettre de construire ce système d’authentification pour nos applications. Dans cet article, nous créerons une page d’enregistrement pour les nouveaux utilisateurs et des pages de connexion et de déconnexion pour les utilisateurs existants.
La principale raison de l’authentification des utilisateurs est de restreindre le contenu. L’authentification garantit que seuls les utilisateurs autorisés ont accès à un système en empêchant les utilisateurs non autorisés d’accéder aux systèmes et potentiellement en les endommageant, en volant des informations ou en causant d’autres problèmes.
Conditions préalables
- Django
- Python 3
J’utiliserai Ubuntu dans ce tutoriel, mais vous pouvez utiliser n’importe quel environnement.
Mise en place de l’environnement
Nous devons d’abord mettre en place un environnement virtuel. La création de projets dans un environnement ségrégué est toujours une bonne pratique pour éviter d’interférer avec d’autres environnements virtuels ou Python installé dans le système.
Nous créerons un nouveau répertoire où notre application sera stockée. Appelons-le new_project
.
$ mkdir new_project
$ cd new_project
Nous créerons ensuite un environnement virtuel dans le new_project
. Nous utiliserons un installateur Python pour installer virtualenv
, qui est un outil pour créer des environnements Python virtuels isolés.
$ pip install virtualenv
Appelons notre nouveau virtuel "venv"
.
$ virtualenv venv
Pour l’activer:
$ source venv/bin/activate
Démarrage du projet Django
Tout d’abord, assurons-nous que Django est installé :
$ pip install Django
Nous utiliserons ensuite django-admin
un outil pour générer un dossier de projet. Appelons le projet accounts
:
$ django-admin startproject accounts
La structure de base de notre projet jusqu’à présent ressemble à ceci :
├── accounts
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Les dossiers ci-dessus sont les suivants:
manage.py
– un utilitaire de ligne de commande qui donne diverses options pour interagir avec ce projet Django.settings.py
– Ce fichier contient tous les paramètres du site. Ici, vous pouvez enregistrer des applications que vous créez, configurez des bases de données, etc.urls.py
– Ce fichier stocke tous les liens vers le projet. Simplement dit, ce fichier donne instruction à Django que si un utilisateur entre dans cette URL, il doit être dirigé vers le site web spécifié ou la vue.
Nous allons maintenant courir des migrations. Changeons le répertoire à l’endroit où le manage.py
le fichier est:
$ cd accounts
La commande makemigrations
regarde à travers tous vos modèles disponibles et crée des migrations pour toutes les tables qui n’existent pas encore. Le La commande migrate
exécute toutes les migrations non appliquées par rapport à votre base de données, en synchronisant essentiellement les changements de votre modèle avec le schéma de base de données. Pour procéder à des migrations:
$ python manage.py makemigrations
$ python manage.py migrate
Nous allons ensuite exécuter le serveur:
$ python manage.py runserver
Le serveur de développement est disponible à l’adresse http://127.0.0.1:8000/. Consultez le lien pour ouvrir le serveur dans le navigateur.
Création de l’application Django
Un projet Django peut avoir de nombreuses applications en vertu de celui-ci. Créons une application, et appelons-la "account"
.
$ python manage.py startapp account
La structure de l’application ressemble à ceci:
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
- Le fichier
models.py
contient les champs et les comportements les plus importants des données que vous stockez. admin.py
C’est là que vous enregistrez les modèles dans votre application avec l’application d’administration Django.views.py
contient des fonctions Python qui prennent les requêtes HTTP et renvoient les réponses HTTP, comme les documents HTML.
Configuration de l’application
Nous configurerons ensuite l’application en l’incluant dans le INSTALLED_APPS
du fichier settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account' #notre application de compte
]
Django Interface d’administration
Django nous permet de créer, lire, mettre à jour et supprimer des opérations sur les modèles directement via son interface d’administration. Pour accéder à l’interface, nous devons créer un utilisateur qui peut se connecter au site d’administration, appelé un superutilisateur:
$ python manage.py createsuperuser
Suivez les messages demandés et créez un superutilisateur:
Pour accéder au site d’administration, entrez http://127.0.0.1:8000/admin dans le navigateur. Inscrivez le nom d’utilisateur et le mot de passe et connectez-vous à:
Jusqu’à présent, nous avons un utilisateur :
Faire les modèles
Nous allons créer un dossier appelé Templates
dans le répertoire racine:
├── db.sqlite3
├── manage.py
├── accounts
├── Templates
└── account
Cela tiendra notre HTML, fichiers CSS et Javascript. Nous configures settings.py
d’inclure notre dossier Templates
:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR/'Templates'], #ici
'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',
],
},
},
]
Créons une simple page d’accueil où les utilisateurs seront redirigés lorsqu’ils se connecteront. Nous utiliserons le cadre Bootstrap, qui est le cadre CSS le plus populaire pour créer des sites web réactifs et mobiles.
Nous allons créer un modèle simple dans le dossier Templates
, créer un nouveau fichier appelé home.html
:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
Nous créons ensuite des vues sur la page d’accueil. Une fonction de vue, abrégée en vue, est une fonction Python qui accepte une requête Web et renvoie une réponse web. En views.py
,
from django.shortcuts import render
#Créez vos vues ici.
def home(request):
return render(request,'home.html')
Chaque page Internet nécessite son URL. De cette façon, votre application sait ce qu’il faut afficher à un utilisateur qui visite cette URL. URLconf est un concept utilisé dans Django ( configurationURL) qui est une collection de motifs que Django va essayer de correspondre avec l’URL demandée pour trouver la bonne vue.
En urls.py
, ajouter le code suivant:
from django.contrib import admin
from django.urls import path
from account import views #here
urlpatterns = [
path('admin/', admin.site.urls),
path('home/', views.home, name='home'), #ici
]
Super, nous avons une page d’accueil. Exécuter le serveur:
Nous devrions ensuite créer un modèle qui peut être hérité par d’autres modèles. Appelons-le base.html
:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>{% block title %} Simple site {% endblock %}</title>
</head>
<body>
{% block body %}
<header class = "header fixed-top">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="true" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
{% if user.is_authenticated %}
<ul class="navbar-nav ms-auto">
<li class="nav-item active">
<li class="nav-item">
<a class="nav-item nav-link dropdown-toggle mr-md-2" href="#" id="userMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{user.username}}</a>
</li>
<li class="nav-item">
<a class="btn btn-primary ml-auto"href="#">Log out<span class="sr-only"></span></a>
</li>
</ul>
</div>
</div>
{% else %}
<button type="button" class="navbar-toggler"
data-toggle="collapse" data-target="#mainMenu" aria-controls="mainMenu" aria-expanded="false" aria-haspopup="true" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> </button>
<form class="form-inline ms-auto">
<a href="#" class="btn btn-secondary" color="white">Log in</a>
<a href="#" class = "btn btn-primary ml-3">Sign up</a>
</form>
{% endif %}
</nav>
</header>
<div class="container">
{% block content %}{% endblock %}
</div>
{% endblock body %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>
Nous voulons que notre site ait une barre de navigation. La barre de navigation doit avoir un bouton de déconnexion si un utilisateur est authentifié (connecté). Leur nom sera affiché sur un autre bouton, à côté du bouton de déconnexion. Cependant, si un utilisateur n’est pas encore connecté, il peut accéder à deux boutons, les boutons d’inscription et de connexion.
Un bloc est utilisé pour passer outre les éléments de modèle spécifiques. Cela signifie qu’un bloc de contenu est annulé par les enfants qui héritent de ce modèle. Cela peut être fait en utilisant le extends
mots-clés dans les modèles pour enfants. Tout à l’intérieur {% block body %}
et {% endblock body %}
apparaîtra dans tous les modèles qui hériteront du modèle de base.
Nous devrions ensuite étendre le contenu du modèle de base à d’autres modèles en utilisant le modèle de base. {% block content %}
attribut.
Réécrivons home.html
pour hériter du modèle de base:
{% extends 'base.html'%}
{% block content%}
<div class="container mt-5">
<h3>Hello {{user}}</h3>
<h2>This is a simple site </h2>
</div>
{% endblock %}
Puisque nous sommes le superutilisateur et que nous nous sommes connectés dans l’interface d’administration, notre nom d’utilisateur a été affiché.
Créons maintenant une simple page de destination qui sera accessible à tout le monde. Dans le dossier Templates
, créer un nouveau fichier nommé landing_page.html
:
{% extends 'base.html'%}
{% block content%}
<div class="container mt-5" style="background-color:#BCD4E6;">
<section class="d-flex align-items-center">
<div class=" mb-5 container">
<div class="row">
<div class="" style="height:120px;">
</div>
<div class="mt-5 col-lg-6 d-flex flex-column justify-content-center">
<h1 ><b>This is login and sign up landing page test!</b></h1>
<h4 class="mt-5">Let's try </h4>
<div >
<div class="mt-5 text-center text-lg-start">
<a href="#" class="btn-get-started scrollto d-inline-flex align-items-center justify-content-center align-self-center">
<a class="btn btn-primary btn-lg px-4 me-sm-3" href="#">Get Started</a>
<a class="btn btn-secondary btn-lg" href="#" >Log in</a>
</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Footer-->
<footer class="container py-2 mt-5 bg-dark">
<div class="container px-5 "><p class="m-0 text-center text-white">Copyright © Me 2022</p></div>
</footer>
</div>
{% endblock%}
Créons ensuite son point de vue. En views.py
:
def landing_page(request):
return render(request,'landing_page.html')
Nous lions ensuite les vues aux URL. En urls.py
:
path('', views.landing_page, name='landing_page'),
Notre page d’accueil ressemble à ceci :
La page d’inscription
Faisons maintenant une page d’inscription qui permet aux utilisateurs d’entrer leurs détails. Tout d’abord, créons son point de vue :
from django.shortcuts import render, redirect #add redirect
from django.contrib.auth import login
from django.contrib.auth.forms import UserCreationForm
def signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('home')
else:
form = UserCreationForm()
return render(request, 'signup.html', {'form': form})
Django inclut un système d’authentification utilisateur. Pour gérer la création de nouveaux utilisateurs, il fournit un formulaire appelé UserCreationForm
(qui hérite de la ModelForm
classe). Il contient trois champs: username
, password1
, et password2
(pour confirmation par mot de passe). À utiliser UserCreationForm
, nous l’importons d’abord de django.contrib.auth.forms
.
login()
utilise le cadre de session de Django pour sauvegarder l’ID de l’utilisateur dans la session. Le formulaire devrait nous rediriger vers la page d’accueil en utilisant redirect()
fonction si le formulaire est valide.
En urls.py
, nous ajoutons un chemin pour s’inscrire sur les points de vue:
path('signup/', views.signup, name='signup'),
dans le dossier Templates
, nous créons un nouveau fichier, signup.html
:
{% extends 'base.html' %}
{% block content %}
<div class="container mt-5">
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}
{% endfor %}
</p>
{% endfor %}
<button type="submit" class="btn btn-primary">Create an account</button>
</form>
</div>
{% endblock %}
Nous rendons le formulaire dans le gabarit en itérant à travers celui-ci. Nous utilisons {% csrf_token %}
tag pour éviter les attaques malveillantes. Lors du rendu de la page, il génère un jeton sur le serveur et assure qu’il est vérifié par recoupement pour les requêtes subséquentes. Si les demandes entrantes n’ont pas le jeton, elles ne sont tout simplement pas traitées.
S’il y a une erreur dans n’importe quel champ, il mettra en évidence un message d’erreur en couleur rouge. Nous ajoutons ensuite un bouton pour créer un nouveau compte:
Après avoir rempli les détails, il nous redirige vers la page d’accueil, avec notre nouveau nom mis à jour. Pour confirmer les utilisateurs signés, accédons à l’interface administrateur.
Lions-le maintenant le bouton démarre au formulaire d’inscription sur landing_page.html
:
<a class="btn btn-primary btn-lg px-4 me-sm-3" href="{% url 'signup' %}" >Get Started</a>
En cliquant sur le bouton
La page de connexion
Maintenant que nous avons mis en place le formulaire d’inscription, créons une page pour les utilisateurs connectés. En views.py
:
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm #Add AuthenticationForm
def log_in(request):
if request.method == "POST":
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request,user)
return redirect('home')
else:
form = AuthenticationForm()
return render(request,'login.html', {"form":form})
Django nous permet d’utiliser sa forme intégrée pour gérer la connexion. AuthenticateForm
. Si le formulaire est valide, il obtient l’utilisateur dont les données d’entrée correspondent aux utilisateurs existants.
En urls.py
, ajouter le texte suivant:
path('login/', views.log_in, name='login'),
Nous créons ensuite un nouveau modèle dans le Templates
plieuse, login.html
:
{% extends 'base.html' %}
{% block body %}
<div class="container">
<h1 class="text-center logo my-4">
<a href="{% url 'home' %}">Simple site</a>
</h1>
<div class="row justify-content-center">
<div class="col-lg-4 col-md-6 col-sm-8">
<div class="card">
<div class="card-body">
<h3 class="card-title">Log in</h3>
<form method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary btn-block">Log in</button>
</form>
</div>
<div class="card-footer text-muted text-center">
New to Simple site? <a href="{% url 'signup' %}">Sign up</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Ici, nous nous assurons que csrf_token
est pris en charge. Nous rendons le formulaire d’enregistrement. Soyons update la landing_page.html
Modèle:
<a class="btn btn-secondary btn-lg" href="{% url 'login'%}" >Log in</a>
Retournez au bouton de connexion sur la page de destination; il nous amène à la page de connexion:
Après la connexion, nous sommes redirigés vers la page d’accueil:
La page de déconnecte
Un utilisateur doit pouvoir se déconnecter à tout moment. En views.py
:
from django.contrib.auth import login, logout
def log_out(request):
logout(request)
return redirect('landing_page')
La fonction logout()
de Django supprime l’identifiant de l’utilisateur authentifié de la demande et bouffe ses données de session.
Notez que nous ne pouvons pas nommer notre fonction logout()
car il sera en conflit avec les fonctions de Django intégrées. En urls.py
, ajouter le texte suivant:
path('logout/', views.log_out, name='logout'),
Nous devrions maintenant relier les chemins à la navbar button pour une accessibilité aisée, base.html
:
<a class="btn btn-primary ml-auto"href="{% url 'logout'%}">Log out<span class="sr-only"></span></a>
<form class="form-inline ms-auto" >
<a href="{% url 'login'%}" class="btn btn-secondary" color="white">Log in</a>
<a href="{% url 'signup'%}" class = "btn btn-primary ml-3">Sign up</a>
</form>
Super. Nous pouvons maintenant y accéder en utilisant les boutons de la barre de navigation. Lorsque nous cliquons sur le bouton de déconnexion, il nous redirige vers la page de destination, où nous devons nous connecter ou nous inscrire à nouveau pour accéder à la page d’accueil.
Conclusion
Félicitations. Vous avez réussi à créer un système d’authentification dans le cadre de Django. Comme vous l’avez déjà vu, Django nous offre des outils pratiques pour le processus d’authentification, avec des fonctions comme login()
, et logout()
, ainsi qu’avec des formes préconstruites telles que UserCreationForm
et AuthenticateForm
.