PassPort
Deuxième tour : l’idée est d’intégrer une deux autres stratégies dans le premier projet.
GitHub
Actions
Je ne sais pas si c’est le plus simple mais c’est celui qui m’a paru le plus évident pour commencer … Alors dans l’ordre :
- Création d’une application dans GitHub (ici)
- Mise à jour de la configuration pour intégration des clés,
- Installation du package :
npm install passport-github2
(comme, je suis en Npm 5 plus besoin du –save), - Intégration de la nouvelle stratégie (pris sur l’exemple …)
- Ajout des deux routes,
- Test manuelle : semble bien fonctionner. Le souci semble être plus dans le lien avec l’appli …
Bon par contre, j’ai eu quelques petites contrariétés, mais qui sont dus à des mauvaises manipulations de ma part :
- Récupération d’une email: l’exemple n’est pas bon au niveau du scope. Il faut mettre la demande scope dans la route mais également dans la stratégie. Dans ce cas, Passport va faire un appel de plus pour récupérer l’adresse mail
- Flash Message : c’est pour bien écrit pour que les flash-messages fonctionnent, il faut mettre failureFlash : true en paramètre …
Bilan
Pour le coup, c’était simple. Les problèmes que j’ai rencontré étaient clairement de ma responsabilité donc je vois bien l’intérêt.
Un petit Jeton
Préambule
Il existe des stratégie qui permette de gérer une identification avec un jeton JWT mais je n’ai pas trouvé de solution qui s’associait avec ce que j’avais déjà implémenté. Donc, je suis parti sur une solution “simple” reprenant différente lecture et formation déjà réalisée
Actions
J’ai défini une nouvelle route de login qui utilise la stratégie locale mais pas en tant que MiddleWare mais en tant que service appelé. Je passe en paramètre req & res et effectue un retour standard avec génération d’un jeton JWT via la librairie jsonwetoken :
router.post('/login', (req, res, next) => {
// Appel de passport
passport.authenticate('local-login', { session : false }
, (err, data, message) => {
// Si j'ai une erreur dans le traitement du côté de passport
if(err) { return res.status(500).json({ success: false, message: err.message }); }
// Si j'ai pas de data = user
if(!data) { return res.status(401).json( { success: false, message : message }); }
// J'ai bien un user : je lui retourne un token
const info = {
success: true
, message: 'Authenticated'
, data: {
// Génération du token avec la librairie jsonwebtoken
token : jwt.sign({ id: data._id }, config.app.secret, { expiresIn: '24h'} )
, username: data.username
}
};
return res.status(200).json(info);
})(req, res); // Authenticate
});
Ensuite, j’ai crée un nouveau MiddleWare qui vérifie que le jeton est valide :
router.use((req, res, next) => {
// Récupération du token
const token = req.headers['authorization'];
// !token ?
if (!token) { res.json({ success: false, message: 'No token provided' }); return; }
// Le token ayant été "crée" par jwt, on lui demande de recommencer le travail :)
jwt.verify(token, config.app.secret, (err, decoded) => {
if (err) { res.json({ success: false, message: 'Token invalid: ' + err }); return ;}
// Ajout de ce qui a été décode (user._id) pour utilisation dans la suite du process
req.decoded = decoded;
// Passage à la méthode suivante
next();
});
});
Finalement, j’ai une route située après ce MiddleWare qui me permet de répondre à la requête de l’utilisateur :
router.get('/ping', (req, res, next) => {
//res.send(req.decoded);
// Recherche
Account.findOne({ _id: req.decoded.id }).select('username email').exec((err, user) => {
// err ?
if (err) { res.json({ success: false, message: err }); return; }
// Check if user was found in database
if (!user) {
res.json({ success: false, message: 'User not found' });
} else {
res.json({ success: true, user: user });
}
});
});
Test
Merci Postman !
Bilan
Après une 2ème journée, je comprends mieux l’intérêt : ca fait pas tout mais ça aide bien ! Maintenant, il faudrait voir comment partager une identification entre GitHub, Local & Jwt mais ça ce sera pour un autre demain !