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

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.

enter image description here

Quand cette route est atteint, nous pouvons également voir dans la console que l'utilisateur est sérialisé.

enter image description here

Alors que la prochaine?

C'est là que je me perds. J'ai quelques questions.

  1. Est maintenant l'utilisateur dans une session sur mon serveur?
  2. devrais-je envoyer le req.session.passport.user retour au client?
  3. 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.

23
demandé sur Joe Lloyd 2016-04-07 23:19:42

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!'
    });
});
41
répondu hassansin 2016-04-10 09:20:40

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.

8
répondu yeiniel 2016-04-14 16:53:48

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
});
1
répondu Michael Hamilton 2016-04-13 16:15:13

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

0
répondu tcmoore 2016-04-08 20:24:53

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 .

0
répondu Jack 2018-07-22 04:09:50