• Aucun résultat trouvé

Passons aux vues

IV. Des outils supplémentaires 178

16.2. Passons aux vues

Maintenant que nous avons assimilé les bases, il est temps de passer aux vues permettant à un utilisateur de se connecter, déconnecter, etc. Nous n’aborderons pas ici l’enregistrement de nouveaux utilisateurs. En effet, nous avons déjà montré la fonction à utiliser, et le reste est tout à fait classique : un formulaire, une vue pour récupérer et enregistrer les informations, un template…

16.2.1. La connexion

Nous avons désormais des utilisateurs, ils n’ont plus qu’à se connecter ! Pour ce faire, nous aurons besoin des éléments suivants :

— Un formulaire pour récupérer le nom d’utilisateur et le mot de passe ;

— Un template pour afficher ce formulaire ;

— Une vue pour récupérer les données, les vérifier, et connecter l’utilisateur.

Commençons par le formulaire. Il ne nous faut que deux choses : le nom d’utilisateur et le mot de passe. Autrement dit, le formulaire est très simple. Nous le plaçons dans blog/forms.py:

Listing 99 – Notre formulaire de connexion (blog/forms.py)

Rien de compliqué, si ce n’est le widget utilisé : forms.PasswordInput permet d’avoir une boîte de saisie dont les caractères seront masqués, afin d’éviter que le mot de passe ne soit affiché en clair lors de sa saisie.

Passons au template :

Listing 100 – Notre template de connexion (templates/login.html)

La nouveauté ici est la variable user, qui contient l’instance User de l’utilisateur s’il est connecté, ou une instance de la classe AnonymousUser. La classeAnonymousUser est utilisée pour indiquer que le visiteur n’est pas un utilisateur connecté.UseretAnonymousUserpartagent certaines méthodes commeis_authenticated, qui permet de définir si le visiteur est connecté ou non. Une instance User retournera toujours True, tandis qu’une instance AnonymousUser retournera toujours False. La variable user dans les templates est ajoutée par un processeur de contexte inclus par défaut. Sa valeur est disponible dans les templates viarequests.user Notez l’affichage du message d’erreur si la combinaison utilisateur/mot de passe est incorrecte.

Pour terminer, passons à la partie intéressante : la vue. Récapitulons auparavant tout ce qu’elle doit faire :

1. Afficher le formulaire ;

2. Après la saisie par l’utilisateur, récupérer les données ;

3. Vérifier si les données entrées correspondent bien à un utilisateur ; 4. Si c’est le cas, le connecter et le rediriger vers une autre page ; 5. Sinon, afficher un message d’erreur.

Vous savez d’ores et déjà comment réaliser les étapes 1, 2 et 5. Reste à savoir comment vérifier si les données sont correctes, et si c’est le cas connecter l’utilisateur. Pour cela, Django fournit deux fonctions,authenticateetlogin, toutes deux situées dans le moduledjango.contrib.auth. Voici comment elles fonctionnent :

— authenticate(username=nom, password=mdp) : si la combinaison utilisateur/mot de passe est correcte, authenticate renvoie l’entrée du modèleUser correspondante.

Si ce n’est pas le cas, la fonction renvoie None.

— login(request, user) : permet de connecter l’utilisateur. La fonction prend l’objet HttpRequest passé à la vue par le framework, et l’instance de User de l’utilisateur à connecter.

!

Attention ! Avant d’utiliserlogin avec un utilisateur, vous devez avant tout avoir utilisé authenticate avec le nom d’utilisateur et le mot de passe correspondant, sans quoi login n’acceptera pas la connexion. Il s’agit d’une mesure de sécurité.

Désormais, nous avons tout ce qu’il nous faut pour coder notre vue. Voici notre exemple :

Listing 101 – La vue de connexion (blog/views.py) Et finalement la directive de routage dans crepes_bretonnes/urls.py:

Vous pouvez désormais essayer de vous connecter depuis l’adresse /connexion. Vous devrez soit créer un compte manuellement dans la console si cela n’a pas été fait auparavant grâce à la commande manage.py createsuperuser, soit renseigner le nom d’utilisateur et le mot de passe du compte super-utilisateur que vous avez déjà créé.

Si vous entrez une mauvaise combinaison, un message d’erreur sera affiché, sinon, vous serez connectés !

16.2.2. La déconnexion

Heureusement, la déconnexion est beaucoup plus simple que la connexion. En effet, il suffit d’appeler la fonction logout dedjango.contrib.auth. Il n’y a même pas besoin de vérifier si le visiteur est connecté ou non (mais libre à vous de le faire si vous souhaitez ajouter un message d’erreur si ce n’est pas le cas par exemple).

Listing 102 – Notre vue de déconnexion (blog/views.py) Avec comme routage :

C’est aussi simple que cela !

16.2.3. Intéragir avec le profil utilisateur

Comme nos utilisateurs peuvent désormais se connecter et se déconnecter, il ne reste plus qu’à pouvoir interagir avec eux. Nous avons vu précédemment qu’un processeur de contexte se chargeait d’ajouter une variable reprenant l’instance User de l’utilisateur dans les templates. Il en va de même pour les vues.

En effet, l’objet HttpRequest passé à la vue contient également un attribut user qui renvoie l’objet utilisateur du visiteur. Celui-ci peut, encore une fois, être une instance User s’il est connecté, ou AnonymousUser si ce n’est pas le cas. Exemple dans une vue :

Maintenant, imaginons que nous souhaitions autoriser l’accès de certaines vues uniquement aux utilisateurs connectés. Nous pourrions vérifier si l’utilisateur est connecté, et si ce n’est pas le cas le rediriger vers une autre page, mais cela serait lourd et redondant. Pour éviter de se répéter, Django fournit un décorateur très pratique qui nous permet de nous assurer qu’uniquement des visiteurs authentifiés accèdent à la vue. Son nom est login_required et il se situe dans django.contrib.auth.decorators. En voici un exemple d’utilisation :

Listing 103 – une vue qui nécessite de s’authentifier.

Si l’utilisateur n’est pas connecté, il sera redirigé vers l’URL de la vue de connexion. Cette URL est normalement définie depuis la variable LOGIN_URL dans votre settings.py. Si ce n’est pas fait, la valeur par défaut est '/accounts/login/'. Comme nous avons utilisé l’URL '/connexion/' tout à l’heure, réindiquons-la ici :

Il faut savoir que si l’utilisateur n’est pas connecté, non seulement il sera redirigé vers '/connexion/', mais l’URL complète de la redirection sera '/connexion/?next=/bon jour/'. En effet, Django ajoute un paramètre GET appelé next qui contient l’URL d’où provient la redirection. Si vous le souhaitez, vous pouvez récupérer ce paramètre dans la vue gérant la connexion, et ensuite rediriger l’utilisateur vers l’URL fournie. Néanmoins, ce n’est pas obligatoire.

Sachez que vous pouvez également préciser le nom de ce paramètre (au lieu de next par défaut), via l’argument redirect_field_namedu décorateur :

Vous pouvez également spécifier une autre URL de redirection pour la connexion (au lieu de prendreLOGIN_URL dans lesettings.py) :

Enfin, comme pour les modèles, Django utilise des signaux pour certains événements utilisa-teurs :

— user_logged_in : Envoyé quand un utilisateur se connecte, avecrequest etuser en argument ;

— user_logged_out : Envoyé quand un utilisateur se déconnecte, avecrequest et user en argument ;

— user_login_failed : Envoyé quand une tentative de connexion a échoué avec creden-tials en argument, contenant des informations sur la tentative.