TP - connexion et déconnexion¶
Nous allons à présent nous attaquer à une fonctionnalité indispensable pour tout forum : la connexion des utilisateurs. A la fin de ce travail pratique, la page suivante s’affichera :

En rétrécissant la fenêtre, nous obtenons ce résultat :

Cette page est accessible à partir d’un bouton dans la barre de navigation. A côté du bouton login
de la barre de navigation, le bouton Créer un compte
redirige vers la page nouveau_compte
(qui n’existe pas encore).

Une alerte bleue invite l’utilisateur à créer un compte s’il n’en a pas encore.

Un clic sur le bouton login
ou un appui sur la touche enter
depuis la zone de texte mot de passe
vérifie si le nom d’utilisateur existe et si le mot de passe est correct. Si ces conditions sont vérifiées, l’utilisateur est alors connecté. Dans le cas contraire, un message s’affiche :

Lorsque l’utilisateur est connecté, sa session est sauvegardée dans le cache de son navigateur, il est redirigé vers la page d’accueil et son nom d’utilisateur s’affiche dans la barre de navigation. Les boutons Créer un compte
et Login
disparaissent au profit du bouton Logout
qui permet à l’utilisateur de se déconnecter.

Si l’utilisateur clique sur le bouton Logout
, sa session (celle qui est stockée dans le navigateur internet) est supprimée et il est redirigé vers la page de login.
Pistes¶
- Comme la page pour créer un compte n’existe pas encore, vous pouvez tester votre page de connexion avec l’utilisateur
samf
, déjà présent dans votre base de données, qui a le mot de passehello
- Pour écrire les instructions nécessaires à la mise en place de la session, utilisez la procédure vue au chapitre précédent
Bon travail !
Correction¶
Code côté serveur¶
Pour que cette page s’affiche, il faut commencer par créer un fichier EJS
et l’indiquer dans routes.js
. Ici, le nom de login.ejs
a été choisi pour ce fichier, qui se trouve dans le dossier views
. Le fichier routes.js
a alors besoin d’un nouveau app.get()
pour afficher cette page.
app.get('/login', function(req, res) {
res.render('login.ejs');
});
Il s’agit ensuite de vérifier, avec socket.js
, si le nom d’utilisateur existe et correspond avec le mot de passe :
socket.on('login', function (login) {
var requete_sql = '\
SELECT mot_de_passe \
FROM users \
WHERE nom_utilisateur = ??';
var inserts = [login.nom_utilisateur];
requete_sql = sql.preparer(mysql, requete_sql, inserts);
sql.requete(mysql, sql, requete_sql, function(results) {
try {
/* ce bloc try-catch sert à détecter une erreur pouvant survenir
lorsqu'on demande le mot de passe d'un utilisateur inexistant */
if (login.password == results[0].mot_de_passe) {
session.creation_jeton(mysql, sql, base64url,
crypto, socket, login.nom_utilisateur);
} else {
socket.emit('erreur_login');
}
}
catch(e) {
socket.emit('erreur_login');
}
});
});
Lors de l’appel de cette fonction, une requête SQL
est exécutée pour savoir si le mot de passe correspond à l’utilisateur. Si tout est correct, la fonction creation_jeton
est exécutée, et cette fonction redirige l’utilisateur vers la page token/:jeton
. Dans le cas contraire, socket.io
émet l’événement erreur_login
qui, sur le côté client, fera apparaître un message d’erreur.
Nous vérifions alors ce jeton d’authentification et enregistrons la session. Pour ce faire, nous ajoutons un app.get
qui s’exécutera lorsque la page token/:token
sera demandée :
app.get('/token/:token', function(req, res) {
session.conv_jeton(mysql, sql, req.params.token, function(nom_utilisateur) {
session.login(res, req.session, nom_utilisateur, function() {
// le chiffre 301 indique au navigateur web que la page va être redirigée
res.redirect(301, '/');
});
});
});
Il manque encore la gestion de la page Logout
dans routes.js
:
app.get('/logout', function(req, res) {
session.logout(req.session);
res.redirect(301, '/login');
});
Après la suppression de la session, l’utilisateur est redirigé vers la page de login.
Code côté client¶
Commençons par le code EJS
de la page principale, login.ejs
:
<!DOCTYPE html>
<html lang="fr">
<head>
<% include balise_head %>
<script src="static/js/login.js"></script>
</head>
<body>
<% include barre_navigation %>
<div class="container">
<div class="row">
<div class="col-lg-offset-2 col-md-offset-1 col-md-10 col-lg-8
blanc corps_page">
<center>
<div class="alert alert-info">
Vous n'avez pas encore de compte ?
<a href="nouveau_compte">Inscrivez-vous</a> maintenant !
</div>
</center>
<form class="form-horizontal" style="padding-right:20px;">
<div class="form-group">
<h4 class="gros_titre">Se connecter</h4>
</div>
<div class="row">
<div class="form-group" id="form_login_utilisateur">
<label for="login_utilisateur" class="col-lg-3 col-sm-4 control-label">
Nom d'utilisateur
</label>
<div class="col-lg-9 col-sm-8">
<input type="text" class="form-control" id="login_utilisateur">
<span class="help-block message_erreur"
id="login_incorrect"
style="position: relative; top: 6px;">
Le nom d'utilisateur ou le mot de passe est incorrect.
</span>
</div>
</div>
</div>
<div class="row">
<div class="form-group" id="form_login_password">
<label for="login_password" class="col-lg-3 col-sm-4 control-label">
Mot de passe
</label>
<div class="col-lg-9 col-sm-8">
<input type="password"
class="form-control"
id="login_password"
onkeypress="verifier_enter(event, this, login);">
</div>
</div>
</div>
<div class="form-group">
<span
class="pull-right btn btn-primary"
style="margin-top: -8px; margin-bottom: 16px;"
onclick="login();">
Login
</span>
</div>
</form>
<div class="col-lg-offset-2 col-md-offset-1"></div>
</div>
</div>
</body>
</html>
Pour fonctionner correctement, cette page a besoin des fonctions login()
, verifier_enter()
et de la gestion de plusieurs événements socket
. Nous allons donc créer un nouveau fichier javascript
, login.js
:
// cette fonction envoie l'événement socket "login"
function login() {
socket.emit('login', {
nom_utilisateur : byId('login_utilisateur').value,
password : byId('login_password').value
});
}
function verifier_enter(event, form, callback) {
// fonction tirée de http://stackoverflow.com/questions/14251676/
var code = (event.keyCode ? event.keyCode : event.which);
if(code === 13) {
callback();
}
}
// met les zones de texte en rouge et affiche le message d'erreur
socket.on('erreur_login', function() {
byId('form_login_utilisateur').className += ' has-error';
byId('form_login_password').className += ' has-error';
byId('login_incorrect').style.display = 'inline';
});
// redirige l'utilisateur vers l'URL indiquée dans l'événement socket
// (en l'occurence, la page "token")
socket.on('redirection', function(url) {
window.location.assign(url);
});
Maintenant, la page Login
vérifie si le nom d’utilisateur est correct et redirige l’utilisateur vers la page d’accueil tout enregistrant le nom d’utilisateur dans la session du navigateur internet.