\chapter{Authentification} Comme on l'a vu dans la partie sur le modèle, nous souhaitons que le créateur d'une liste puisse retrouver facilement les éléments qu'il aura créée. Ce dont nous n'avons pas parlé cependant, c'est la manière dont l'utilisateur va pouvoir créer son compte et s'authentifier. La \href{https://docs.djangoproject.com/en/stable/topics/auth/}{documentation} est très complète, nous allons essayer de la simplifier au maximum. Accrochez-vous, le sujet peut être complexe. \section{Mécanisme d'authentification} On peut schématiser le flux d'authentification de la manière suivante : En gros: \begin{enumerate} \item La personne accède à une URL qui est protégée (voir les décorateurs @login\_required et le mixin LoginRequiredMixin) \item Le framework détecte qu'il est nécessaire pour la personne de se connecter (grâce à un paramètre type LOGIN\_URL) \item Le framework présente une page de connexion ou un mécanisme d'accès pour la personne (template à définir) \item Le framework récupère les informations du formulaire, et les transmets aux différents backends d'authentification, dans l'ordre \item Chaque backend va appliquer la méthode \texttt{authenticate} en cascade, jusqu'à ce qu'un backend réponde True ou qu'aucun ne réponde \item La réponse de la méthode authenticate doit être une instance d'un utilisateur, tel que définit parmi les paramètres généraux de l'application. \end{enumerate} En résumé (bis): \begin{enumerate} \item Une personne souhaite se connecter; \item Les backends d'authentification s'enchaîne jusqu'à trouver une bonne correspondance. Si aucune correspondance n'est trouvée, on envoie la personne sur les roses. \item Si OK, on retourne une instance de type current\_user, qui pourra être utilisée de manière uniforme dans l'application. \end{enumerate} Ci-dessous, on définit deux backends différents pour mieux comprendre les différentes possibilités: \begin{enumerate} \item Une authentification par jeton \item Une authentification LDAP \end{enumerate} \begin{minted}{python} from datetime import datetime from django.contrib.auth import backends, get_user_model from django.db.models import Q from accounts.models import Token UserModel = get_user_model() class TokenBackend(backends.ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): """Authentifie l'utilisateur sur base d'un jeton qu'il a reçu. On regarde la date de validité de chaque jeton avant d'autoriser l'accès. """ token = kwargs.get("token", None) current_token = Token.objects.filter( token=token, validity_date__gte=datetime.now() ).first() if current_token: user = current_token.user current_token.last_used_date = datetime.now() current_token.save() return user return None \end{minted}