A propos de l'auteur

Philip Kiely est développeur, écrivain et entrepreneur. Il est étudiant au Grinnell College (promotion 2020).
Plus à propos
Philippe
Kiely

L'une des principales raisons de développer un site dynamique est d'authentifier les utilisateurs et de restreindre le contenu. Django fournit un puissant modèle utilisateur prêt à l'emploi, et dans cet article, nous allons découvrir la meilleure façon de fournir des flux d'authentification utilisateur sécurisés et intuitifs.

Il existe deux types de sites Web: statiques et dynamiques. Django est un framework pour développer des sites Web dynamiques. Alors qu'un site Web statique est celui qui présente uniquement des informations, il n'y a pas d'interaction (au-delà des simples demandes de page) qui est enregistrée sur un serveur. Dans un site Web statique, le serveur envoie du HTML, du CSS et du JavaScript à un client et c'est tout. Plus de fonctionnalités nécessitent un site Web dynamique, où le serveur stocke des informations et répond à l'interaction de l'utilisateur au-delà de la simple diffusion de pages. L'une des principales raisons de développer un site dynamique est d'authentifier les utilisateurs et de restreindre le contenu.

Écrire, déployer et administrer un site Web statique est environ un ordre de grandeur plus facile, moins cher et plus sécurisé qu'un site dynamique. Par conséquent, vous ne devez créer un site Web dynamique que si les capacités supplémentaires du paradigme dynamique sont nécessaires pour votre projet. Django simplifie et rationalise le processus de création d'un site dynamique avec ses composants intégrés. En tant que l'un des principaux composants d'une application Web dynamique, l'objet «compte d'utilisateur», comme la roue, est tentant de réinventer, mais la forme standard convient à la plupart des utilisations. Django fournit un puissant modèle utilisateur prêt à l'emploi, et dans cet article, nous allons découvrir la meilleure façon de fournir des flux d'authentification utilisateur sécurisés et intuitifs.

Mise en place

Si vous souhaitez créer votre propre application Django pour expérimenter les concepts de cet article, vous pouvez créer un répertoire (et de préférence un environnement virtuel), puis exécuter les commandes suivantes:

installer pip django
django-admin startproject PROJECTNAME
cd PROJECTNAME
python manage.py startapp APPNAME
migration de python manage.py
python manage.py runserver

Si vous cherchez une procédure pas à pas pour créer votre premier projet Django, le propre site Web de Django en offre un excellent. Dans cet article, nous n'utilisons pas d'exemple de projet, mais les concepts abordés s'appliqueront à presque toutes les applications Django.

Modèle utilisateur standard

Fondamentalement, le concept de compte d'utilisateur existe pour deux raisons: le contrôle d'accès et l'état personnalisé de l'application. Le contrôle d'accès est l'idée que les ressources d'un système ne sont disponibles que pour certains utilisateurs. L'état personnalisé dépend fortement du but de l'application, mais peut inclure des paramètres, des données ou tout autre enregistrement spécifique à un utilisateur individuel. Le stock de Django Utilisateur Le modèle fournit des approches sensées pour les deux cas d'utilisation.

Au départ, il existe deux types d'utilisateurs dans une application Django: les comptes de superutilisateur et les utilisateurs réguliers. Les superutilisateurs ont tous les attributs et privilèges des comptes réguliers, mais ont également accès au panneau d'administration de Django, une application puissante que nous explorerons en détail dans un prochain article. Essentiellement, les superutilisateurs peuvent créer, modifier ou supprimer toutes les données de l'application, y compris d'autres comptes d'utilisateurs.

Fondamentalement, le concept de compte d'utilisateur existe pour deux raisons: le contrôle d'accès et l'état personnalisé de l'application.

Pour créer un superutilisateur sur votre propre application Django, exécutez:

python manage.py crée un superutilisateur

L'autre avantage d'un compte d'utilisateur est le stockage de données personnalisées dans la base de données. Par défaut, Django ne nécessite qu'un nom d'utilisateur et un mot de passe, mais fournit des champs facultatifs permettant aux utilisateurs d'entrer leur prénom, nom et adresse e-mail. Vous pouvez lire une référence complète du modèle sur le site web de Django. Nous discuterons de l'extension de ce modèle ci-dessous.

Sécurité et fiabilité

Django inclut un middleware de gestion de mot de passe substantiel avec le modèle utilisateur. Les mots de passe des utilisateurs doivent comporter au moins 8 caractères, pas entièrement des chiffres, ne pas correspondre trop étroitement au nom d'utilisateur et ne pas figurer sur une liste des 20 000 mots de passe les plus courants. Les formulaires de stock Django valident ces exigences. Lorsqu'un mot de passe est envoyé au serveur, il est crypté avant d'être stocké, par défaut à l'aide de l'algorithme PBKDF2 avec un hachage SHA256. Dans l'ensemble, le système de mot de passe par défaut offre une sécurité robuste sans aucun effort de la part du développeur. Sauf si vous avez une expertise spécifique et une raison impérieuse de changer la façon dont les mots de passe sont traités dans votre application, ne modifiez pas ce comportement.

Une autre fonction intégrée pratique est l'exigence que les noms d'utilisateur soient uniques. Si vous y réfléchissez, s'il y avait deux utilisateurs avec le nom d'utilisateur "djangofan1" et que le serveur recevait une demande de connexion pour ce nom d'utilisateur, il ne saurait pas quel utilisateur essayait d'accéder à l'application. Malheureusement pour eux, le deuxième utilisateur à essayer de s'inscrire avec "djangofan1" devra choisir un nom différent, peut-être "djangofan2". Cette contrainte d'unicité est appliquée au niveau de la base de données mais est à nouveau vérifiée par les formulaires fournis par Django.

Enfin, une note sur la suppression d'utilisateurs. Bien que la suppression d'utilisateurs soit une possibilité, la plupart des applications complexes auront un certain nombre de ressources liées à chaque compte d'utilisateur. Si vous souhaitez supprimer efficacement un utilisateur sans supprimer ces objets attachés, définissez le c'est actif à la place false. Ensuite, ces autres ressources restent associées au compte plutôt que d'être supprimées elles-mêmes, et le compte d'utilisateur peut être réactivé à tout moment par un superutilisateur. Notez que cela ne libère pas le nom d'utilisateur, mais le fait de définir le compte comme inactif conjointement avec la modification du nom d'utilisateur en une valeur unique aléatoire pourrait obtenir le même effet. Enfin, si les politiques de votre site ou la loi locale applicable exigent que les comptes d'utilisateurs soient entièrement supprimables, le c'est actif approche ne sera pas suffisante.

Sauf si vous avez une expertise spécifique et une raison impérieuse de changer la façon dont les mots de passe sont traités dans votre application, ne modifiez pas ce comportement.

Utilisation standard

Lorsque vous souhaitez enregistrer un nouveau compte d'utilisateur, la vue pour le faire ressemblera probablement à ce qui suit dans views.py:

à partir de django.shortcuts importer le rendu, rediriger
à partir de django.contrib.auth importer authentifier, se connecter
à partir de django.contrib.auth.forms import UserCreationForm

inscription par défaut (demande):
    si request.user.is_authenticated:
        renvoyer la redirection ('/')
    si request.method == 'POST':
        form = UserCreationForm (request.POST)
        si form.is_valid ():
            form.save ()
            username = form.cleaned_data.get ('username')
            mot de passe = form.cleaned_data.get ('password1')
            utilisateur = authentifier (nom d'utilisateur = nom d'utilisateur, mot de passe = mot de passe)
            connexion (demande, utilisateur)
            renvoyer la redirection ('/')
        autre:
            return render (request, 'signup.html', {'form': form})
    autre:
        form = UserCreationForm ()
        return render (request, 'signup.html', {'form': form})

Décomposons cela:

  • Si l'utilisateur est déjà connecté, nous le redirigerons hors de la page d'inscription.
  • Si la méthode de demande est POST, cela signifie que le formulaire de création d'un utilisateur a déjà été rempli et qu'il est temps de créer un utilisateur.
    • Commencez par construire l'objet formulaire sur le backend avec les données fournies par l'utilisateur.
    • Si le formulaire est valide, créez l'utilisateur et connectez-le, puis envoyez-le à la page principale.
    • Sinon, renvoyez-les sur la page de création d'utilisateur avec des informations sur les données non valides (par exemple, ils ont demandé un nom d'utilisateur déjà utilisé).
  • Sinon, l'utilisateur accède à la page pour la première fois et doit recevoir le formulaire de création d'un nouveau compte.

Examinons maintenant la connexion au compte:

à partir de django.shortcuts importer le rendu, rediriger
à partir de django.contrib.auth importer authentifier, se connecter
à partir de django.contrib.auth.forms import AuthenticationForm

sign def (demande):
    si request.user.is_authenticated:
        renvoyer le rendu (demande, 'homepage.html')
    si request.method == 'POST':
        nom d'utilisateur = request.POST['username']
        mot de passe = request.POST['password']
        utilisateur = authentifier (demande, nom d'utilisateur = nom d'utilisateur, mot de passe = mot de passe)
        si l'utilisateur n'est pas Aucun:
            connexion (demande, utilisateur)
            renvoyer la redirection ('/')
        autre:
            form = AuthenticationForm (request.POST)
            return render (request, 'signin.html', {'form': formulaire})
    autre:
        form = AuthenticationForm ()
        return render (request, 'signin.html', {'form': formulaire})

Une autre panne:

  • Si l'utilisateur est déjà connecté, nous le redirigerons hors de la page de connexion.
  • Si la méthode de demande est POST, cela signifie que le formulaire de connexion a été rempli et qu'il est temps d'authentifier l'utilisateur auprès d'un compte.
    • D'abord, authentifiez l'utilisateur avec les données fournies par l'utilisateur
    • Si le nom d'utilisateur et le mot de passe correspondent à un compte, connectez-vous à l'utilisateur
    • Sinon, ramenez-les à la page de connexion avec leurs informations de formulaire pré-remplies
  • Sinon, l'utilisateur accède à la page pour la première fois et doit recevoir le formulaire de connexion.

Enfin, vos utilisateurs pourraient éventuellement vouloir se déconnecter. Le code de base de cette demande est simple:

à partir de django.shortcuts importer le rendu, rediriger
à partir de django.contrib.auth déconnexion d'importation

déconnexion par défaut (demande):
    déconnexion (demande)
    renvoyer la redirection ('/')

Une fois que l'utilisateur a été connecté à son compte et jusqu'à ce qu'il se déconnecte de cet appareil, il a une «session». Pendant ce temps, les requêtes suivantes de son navigateur pourront accéder aux pages de compte uniquement. Un utilisateur peut avoir plusieurs sessions actives en même temps. Par défaut, les sessions n'expirent pas.

Lorsqu'un utilisateur a une session active sur son appareil, il s'enregistrera en tant que Vrai pour le request.user.is_authenticated vérifier. Une autre façon de restreindre les pages aux utilisateurs connectés uniquement est le @Connexion requise décorateur au-dessus d'une fonction. Il existe de nombreuses autres façons d'y parvenir, détaillées ici.

Si ce niveau de configuration est supérieur à ce que vous souhaitez effectuer, il existe une approche encore plus prête à l'emploi pour la gestion des utilisateurs. Ces vues d'authentification de stock fournissent des itinéraires, des vues et des formulaires standard pour la gestion des utilisateurs et peuvent être modifiées en les affectant à des URL personnalisées, en passant des modèles personnalisés ou même en sous-classant les vues pour plus de contrôle.

Extension du modèle utilisateur

En règle générale, vous devez étendre le modèle utilisateur pour fournir des contrôles d'accès plus précis ou stocker davantage de données utilisateur par compte. Nous allons explorer plusieurs cas courants ci-dessous.

Suppression de champs du modèle utilisateur

Contrairement à l'en-tête de cette section, je ne recommande pas réellement d'apporter des modifications directement au modèle utilisateur ou au schéma de base de données associé! Le modèle utilisateur générique est établi par défaut dans votre base de données lors de la configuration d'un nouveau projet Django. Le modèle utilisateur par défaut est tellement lié que sa modification pourrait avoir des effets inattendus sur votre application (en particulier si vous utilisez des bibliothèques tierces), en conséquence, l'ajout ou la suppression de champs n'est pas recommandé et n'est pas facilité par le cadre.

Par défaut, les deux seuls champs requis pour un utilisateur sont le nom d'utilisateur et le mot de passe. Si vous ne souhaitez utiliser aucun des autres champs, ignorez simplement leur existence, car un utilisateur peut être créé sans prénom, nom de famille ou adresse e-mail. Il existe une collection de champs par défaut comme last_login et date_joined qui peuvent également être ignorés si vous ne les souhaitez pas. Si vous aviez une contrainte technique réelle qui nécessitait de supprimer des champs facultatifs du modèle utilisateur, vous le saviez déjà et n'auriez pas besoin de cet article.

Une raison courante pour laquelle vous souhaiterez peut-être supprimer un champ dans le modèle utilisateur est de supprimer le nom d'utilisateur en faveur de l'e-mail en tant qu'identifiant unique. Dans ce cas, lors de la création de l'utilisateur à partir des données du formulaire ou de l'authentification d'une demande, entrez simplement l'adresse e-mail comme nom d'utilisateur en plus de son utilisation dans le champ e-mail. Le champ du nom d'utilisateur appliquera toujours la contrainte d'unicité lorsque les noms d'utilisateur sont formatés en adresses e-mail. Les chaînes sont des chaînes, elles seront traitées de la même manière.

Le modèle utilisateur par défaut est tellement lié que sa modification pourrait avoir des effets inattendus sur votre application, en particulier si vous utilisez des bibliothèques tierces.

Ajout de champs avec un profil

De même, si vous souhaitez stocker des informations supplémentaires sur vos utilisateurs, vous ne devez pas tenter de modifier le modèle utilisateur par défaut. Même pour un seul champ, définissez votre propre objet avec une relation un à un avec les utilisateurs existants. Ce modèle supplémentaire est souvent appelé Profil. Supposons que vous vouliez enregistrer un deuxième prénom et une date de naissance (ddb) pour chaque utilisateur. le Profil serait défini comme suit dans models.py:

à partir des modèles d'importation django.db
depuis django.contrib.auth.models import User

Profil de classe (models.Model):
    user = models.OneToOneField (Utilisateur, on_delete = models.CASCADE)
    middle_name = models.CharField (max_length = 30, blank = True)
    dob = models.DateField (null = True, vide = True)

Contrôle d'accès personnalisé

Votre application peut avoir nécessité une distinction entre différents types d'utilisateurs pour accéder aux informations et aux fonctions. Django fournit un système pour créer un contrôle d'accès personnalisé à granularité fine: autorisations et groupes.

Les autorisations sont des objets qui déterminent l'accès aux ressources. Un utilisateur peut avoir une ou plusieurs autorisations. Par exemple, ils peuvent avoir un accès en lecture à une table de produits et un accès en écriture à une table de clients. L'implémentation exacte des autorisations varie considérablement selon l'application, mais l'approche de Django rend intuitive la définition des autorisations pour les données et l'attribution de ces autorisations aux utilisateurs.

Les applications pour les entreprises et autres grandes organisations implémentent souvent un contrôle d'accès basé sur les rôles. Essentiellement, un utilisateur peut avoir différents rôles, chacun disposant de certaines autorisations. L'outil de Django pour implémenter ce modèle est le Groupe. Un groupe peut avoir un nombre illimité d'autorisations, qui peuvent chacune être attribuées à un nombre quelconque de groupes. Un utilisateur obtient alors des autorisations non pas directement mais par son appartenance à des groupes, ce qui rend l'application plus facile à administrer.

Présentation: intégration d'un fournisseur de paiement

Le processus précis d'intégration d'un processeur de paiement varie considérablement selon l'application et le fournisseur. Cependant, je couvrirai le processus en termes généraux.

L'un des principaux avantages de l'externalisation des paiements est que le fournisseur est responsable du stockage et de la validation des données hautement réglementées telles que les informations de carte de crédit. Le service partage ensuite un jeton d'utilisateur unique avec votre application ainsi que des données sur leur historique de paiement. Comme pour l'ajout du profil, vous pouvez créer un modèle associé au noyau Utilisateur et stocker les données dans ce modèle. Comme pour les mots de passe, il est important de suivre l'intégration donnée avec le fournisseur pour éviter de stocker de manière incorrecte des informations sensibles.

Présentation: connexion sociale

L'autre domaine vaste et complexe que je voudrais aborder brièvement est celui de la connexion sociale. Les grandes plates-formes comme Facebook et Google, ainsi que les petits sites comme GitHub, fournissent des API pour utiliser leurs services pour authentifier les utilisateurs. Semblable à un fournisseur de paiement, cela crée un enregistrement dans votre base de données reliant un compte à un compte dans leur base de données.

Vous souhaiterez peut-être inclure l'authentification sociale dans votre site pour faciliter l'inscription des utilisateurs sans créer un nouvel ensemble d'informations d'identification de connexion. Si votre application cible uniquement les clients qui utilisent déjà un site spécifique offrant une option d'authentification sociale, cela peut vous aider à attirer des utilisateurs de ce marché en abaissant la barrière d'entrée. De plus, si votre application a l'intention d'accéder aux données de l'utilisateur à partir d'un service tiers, la liaison des comptes lors de l'authentification simplifie le processus d'octroi des autorisations.

Cependant, l'utilisation de l'authentification sociale présente des inconvénients. Les modifications ou les pannes d'API du fournisseur tiers peuvent interrompre la disponibilité de votre application ou les activités de développement. En général, les dépendances externes ajoutent de la complexité à l'application. Enfin, il convient de prendre en compte les politiques de collecte et d'utilisation des données de tiers avec lesquelles vous intégrez et assurez-vous qu'elles correspondent à vos attentes et à celles de vos utilisateurs.

Si vous décidez que l'authentification sociale convient à votre application, heureusement, il existe une bibliothèque pour cela. Python Social Auth pour Django est un package permettant d'activer les capacités de l'écosystème d'authentification sociale de Python dans les projets Django.

Emballer

Aussi universel que soit le compte utilisateur, son utilisation généralisée peut conduire à résoudre inutilement les mêmes problèmes. J'espère que cet article vous a montré la gamme de fonctionnalités puissantes disponibles dans Django et vous a donné une compréhension des responsabilités de base d'une application lors de la création de comptes d'utilisateurs.

Django Highlights est une série présentant des concepts importants du développement Web dans Django. Chaque article est écrit comme un guide autonome sur une facette du développement de Django destiné à aider les développeurs et les concepteurs frontaux à approfondir leur compréhension de «l'autre moitié» de la base de code. Ces articles sont principalement conçus pour vous aider à comprendre la théorie et les conventions, mais contiennent des exemples de code, qui sont écrits dans Django 3.0. Plusieurs concepts que nous avons abordés dans cet article, y compris les modèles, les utilisateurs administratifs, les modèles et les formulaires, seront explorés individuellement en détail dans les prochains articles de cette série.

Smashing Editorial
(dm, il)