Session de connexion et de persistance de passeport
Background
j'ai une application moyenne avec des capacités CRUD entièrement testée avec postman. J'ai essayé de persister connexion pour un certain temps maintenant avec pas de chance. J'ai lu et essayé le suivant
- passeport docs
- toon io blog sur la connexion
- session Express
- Scotch io, nœud auth facile
- Plus un buch d'autres documents de lecture légers (beaucoup de questions SO)
mais je n'ai pu enregistrer et connecter qu'un utilisateur, pas persister à me connecter avec une session.
Mon Application
Ici est un lien vers le rapport complet de GitHub (si vous recherchez les derniers changements, vérifiez la branche develop)
ma compréhension de Auth / Login
voici ma compréhension de l'ouverture de session de l'utilisateur avec des exemples de code de mon projet et screenshot de Postman results ainsi que les logs de la console.
configuration du passeport
j'ai l'autorisation suivante.fichier js, il configs passeport
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
module.exports = function(app, user){
app.use(passport.initialize());
app.use(passport.session());
// passport config
passport.use(new LocalStrategy(user.authenticate()));
passport.serializeUser(function(user, done) {
console.log('serializing user: ');
console.log(user);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
user.findById(id, function(err, user) {
console.log('no im not serial');
done(err, user);
});
});
};
Ce qui est appelé dans le fichier du serveur
//code before
var user = require('./models/user.js');
var auth = require('./modules/auth.js')(app, user);
// code after
Routage pour la connexion
dans mes routes j'ai la route de connexion comme suit
router.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.status(401).json({
err: info
});
}
req.logIn(user, function(err) {
if (err) {
return res.status(500).json({
err: 'Could not log in user'
});
}
res.status(200).json({
status: 'Login successful!'
});
});
})(req, res, next);
});
cette route testé avec facteur. J'entre les détails " joe " et "passe" et j'obtiens ce qui suit réponse.
Quand cette route est atteint, nous pouvons également voir dans la console que l'utilisateur est sérialisé.
Alors que la prochaine?
C'est là que je me perds. J'ai quelques questions.
- Est maintenant l'utilisateur dans une session sur mon serveur?
- devrais-je envoyer le
req.session.passport.user
retour au client? - ai-je besoin de la session Identification de toutes les demandes futures?
test de la Session
j'ai une deuxième configuration de route pour tester la session c'est comme suit
router.get('/checkauth', passport.authenticate('local'), function(req, res){
res.status(200).json({
status: 'Login successful!'
});
});
La partie passport.authenticate('local')
(je pensais) est là pour tester si la session de l'utilisateur existe avant de donner accès à la route mais je ne reçois jamais de réponse 200 quand je l'exécute, même après une connexion.
est-ce que cette route attend un req.session.passport.user
passé dans la tête ou comme un argument données sur une requête http qui nécessite auth?
si j'ai manqué quelque chose ou si je comprends quelque chose de mal, s'il vous plaît dites-le moi, toute contribution est appréciée. Merci à tous.
5 réponses
Est maintenant l'utilisateur dans une session sur mon serveur?
Non, Vous devez utiliser le express-session
middleware avant app.use(passport.session());
pour enregistrer la session en mémoire/base de données. Cet middleware est chargé de configurer les cookies pour les navigateurs et convertit les cookies envoyés par les navigateurs en req.session
objet. PassportJS n'utilise cet objet que pour désérialiser davantage l'utilisateur.
dois-je envoyer le req.session.passeport.utilisateur de retourner à la client?
si votre client attend un user
ressource lors de la connexion, alors vous devriez. Sinon, je ne vois aucune raison d'envoyer l'objet utilisateur au client.
ai-je besoin de L'ID de session pour toutes les demandes futures?
Oui, pour toutes les demandes futures, l'id de session est requis. Mais si votre client est un navigateur, vous n'avez pas besoin d'envoyer quoi que ce soit. Le navigateur stockera l'id de session sous forme de cookie et l'enverra pour toutes les demandes ultérieures. jusqu'à l'expiration du cookie. express-session
lira ce cookie et attachera l'objet de session correspondant comme req.session
.
test de la Session
passport.authenticate('local')
sert à authentifier les justificatifs d'identité de l'utilisateur à partir du corps du message. Vous devez utiliser ceci seulement pour la route de connexion.
Mais pour vérifier si l'utilisateur est authentifié dans tous les autres itinéraires, vous pouvez vérifier si req.user
est défini.
function isAuthenticated = function(req,res,next){
if(req.user)
return next();
else
return res.status(401).json({
error: 'User not authenticated'
})
}
router.get('/checkauth', isAuthenticated, function(req, res){
res.status(200).json({
status: 'Login successful!'
});
});
As @hassansin dit que vous devez utiliser un middleware qui implémente la gestion de session. Passeport.session () middleware est de connecter le cadre de passeport à la gestion de session et ne pas mettre en œuvre session par lui-même. Vous pouvez utiliser le express-session
middleware mettre en oeuvre la gestion des sessions. Vous devez modifier votre autorisation.js de la façon suivante
var passport = require('passport');
var session = require('express-session');
var LocalStrategy = require('passport-local').Strategy;
module.exports = function(app, user){
app.use(session({secret: 'some secret value, changeme'}));
app.use(passport.initialize());
app.use(passport.session());
// passport config
passport.use(new LocalStrategy(user.authenticate()));
passport.serializeUser(function(user, done) {
console.log('serializing user: ');
console.log(user);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
user.findById(id, function(err, user) {
console.log('no im not serial');
done(err, user);
});
});
};
notez que dans ce cas, le moteur de session utilise la mémoire mémoire et qu'il ne fonctionne pas si vous mettez à l'échelle votre application et appliquer l'équilibrage de charge. Quand vous atteignez cet état de développement quelque chose comme le connect-redis
session magasin sera nécessaire.
notez également que vous devez changer la valeur secrète utilisée sur l'appel de midleware de session et utiliser la même valeur sur toutes les instances d'application.
selon le documents de passeport,req.user
sera défini pour l'utilisateur authentifié. Pour que cela fonctionne, vous aurez besoin de l' express-session
module. Vous ne devriez pas avoir besoin de quoi que ce soit d'autre que ce que vous avez déjà pour passeport pour travailler.
pour ce qui est de tester la session, vous pouvez avoir une fonction middleware qui vérifie si req.l'utilisateur est définie, si elle l'est, nous savons que l'utilisateur est authentifié, et si elle n'est pas le cas, vous pouvez rediriger l'utilisateur.
vous pourriez Pour exemple avoir une fonction middleware que vous pouvez utiliser sur toutes les routes que vous voulez authentifier.
authentifié.js
module.exports = function (req, res, next) {
// if user is authenticated in the session, carry on
if (req.user) {
next();
}
// if they aren't redirect them to the login page
else {
res.redirect('/login');
}
};
controller
var authenticated = require('./authenticated');
router.get('/protectedpage', authenticated, function(req, res, next) {
//Do something here
});
Je ne sais pas comment vérifier toutes les sessions existantes, mais Passport s'occupe de la délivrance des ID de session. Essayez de vérifier que vous avez req.utilisateur sur votre terminal de test Après ouverture de session
Passeport.js ne fonctionne pas bien car il stocke la session dans le serveur (mauvais et non évolutif). Vous ne voulez pas stocker de données de session dans le serveur (le garder apatride) car vous pouvez alors augmenter l'échelle de vos clusters et gérer plus de requêtes.
Si vous regardez le code dans le Passeport.la bibliothèque js, il n'y a pas grand-chose.. Le construire vous-même peut en fait être plus rapide et plus efficace.
Voici un tutoriel j'ai écrit sur Se connecter à Google dans un bien meilleur .