tutorial node authenticate node.js session authentication express passport.js

node.js - node - Pasaporte de inicio de sesión y sesión persistente



passport local mongoose (5)

Como dice @hassansin, debe usar un middleware que implemente la administración de sesiones. El middleware passport.session () es conectar el marco del pasaporte a la administración de la sesión y no implementar la sesión por sí solo. Puede utilizar el middleware de express-session rápida para implementar la administración de la sesión. Necesitas modificar tu auth.js de la siguiente manera

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); }); }); };

Tenga en cuenta que, en este caso, el motor de sesión está utilizando el almacén de memoria y no funcionó si escala su aplicación y aplica el equilibrio de carga. Cuando llegue a este estado de desarrollo, se necesitará algo como el almacén de sesión de connect-redis .

También tenga en cuenta que necesita cambiar el valor secreto utilizado en la sesión de midleware de sesión y usar el mismo valor en todas las instancias de la aplicación.

Fondo

Tengo una aplicación MEAN con capacidades CRUD completamente probada con cartero. He intentado persistir el inicio de sesión durante bastante tiempo sin suerte. He leído y probado lo siguiente

Pero solo he podido registrar e iniciar sesión en un usuario, no persistir el inicio de sesión con una sesión.

Mi app

Here hay un enlace al repositorio completo de github (si está buscando los últimos cambios verifique la rama de desarrollo)

Mi comprensión de la autenticación / inicio de sesión

Esta es mi comprensión del inicio de sesión del usuario con ejemplos de código de mi proyecto y captura de pantalla de los resultados del cartero, así como los registros de la consola.

Configuración de pasaporte

Tengo el siguiente archivo auth.js, que configura el pasaporte

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); }); }); };

Esto se llama en el archivo del servidor como

//code before var user = require(''./models/user.js''); var auth = require(''./modules/auth.js'')(app, user); // code after

Enrutamiento para inicio de sesión

En mis rutas tengo la ruta de inicio de sesión de la siguiente manera

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); });

Esta ruta funciona según lo probado con el cartero. Ingreso los detalles ''joe'' y ''pass'' y obtengo la siguiente respuesta.

Cuando se llega a esta ruta, también podemos ver en la consola que el usuario está serializado.

Entonces, ¿qué sigue?

Aquí es donde me pierdo. Tengo algunas preguntas.

  1. ¿Está el usuario ahora en una sesión en mi servidor?
  2. ¿Debo enviar el req.session.passport.user nuevo al cliente?
  3. ¿Necesito el ID de sesión en todas las solicitudes futuras?

Probando la sesión

Tengo una segunda configuración de ruta para probar la sesión es la siguiente

router.get(''/checkauth'', passport.authenticate(''local''), function(req, res){ res.status(200).json({ status: ''Login successful!'' }); });

La parte passport.authenticate(''local'') (pensé) está ahí para probar si la sesión del usuario existe antes de dar acceso a la ruta, pero nunca obtengo una respuesta 200 cuando ejecuto esto, incluso después de iniciar sesión.

¿ req.session.passport.user esta ruta un req.session.passport.user pasado en la cabeza o como un argumento de datos en una solicitud http que requiere autenticación?

Si me he perdido algo o estoy entendiendo algo mal, por favor, dígame, cualquier comentario es apreciado. Gracias a todos.


No conozco una forma de verificar todas las sesiones existentes, pero Passport está manejando la emisión de identificadores de sesión. Intente verificar que tiene el usuario requerido en su punto final de prueba después de iniciar sesión


Passport.js no funciona bien ya que almacena la sesión en el servidor (mal y no es escalable). No desea almacenar ningún dato de sesión en el servidor (manteniéndolo sin estado) ya que puede ampliar sus clústeres y manejar más solicitudes.

Si observa el código en la biblioteca Passport.js, no hay mucho ... Construirlo usted mismo puede ser más rápido y más eficiente.

Aquí hay un tutorial que escribí sobre la conexión a Google de una manera mucho mejor .


Según la documentación del pasaporte , req.user se configurará para el usuario autenticado. Sin embargo, para que esto funcione, necesitará el módulo de express-session rápida. No debe necesitar nada más que lo que ya tiene para que el pasaporte funcione.

En lo que respecta a la prueba de la sesión, puede tener una función de middleware que verifique si req.user está configurado, si lo está, sabemos que el usuario está autenticado y si no lo está, puede redirigirlo.

Por ejemplo, podría tener una función de middleware que pueda usar en cualquier ruta que desee autenticar.

authenticated.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''); } };

controlador

var authenticated = require(''./authenticated''); router.get(''/protectedpage'', authenticated, function(req, res, next) { //Do something here });


¿Está el usuario ahora en una sesión en mi servidor?

No, debe usar el middleware de express-session app.use(passport.session()); antes de app.use(passport.session()); para almacenar realmente la sesión en la memoria / base de datos. Este middleware es responsable de configurar las cookies para los navegadores y convierte las cookies enviadas por los navegadores en req.session objeto req.session . PassportJS solo usa ese objeto para deserializar aún más al usuario.

¿Debo enviar el req.session.passport.user de nuevo al cliente?

Si su cliente espera un recurso de user al iniciar sesión, debería hacerlo. De lo contrario, no veo ninguna razón para enviar el objeto de usuario al cliente.

¿Necesito el ID de sesión en todas las solicitudes futuras?

Sí, para todas las solicitudes futuras, se requiere el ID de sesión. Pero si su cliente es un navegador, no necesita enviar nada. El navegador almacenará el ID de sesión como cookie y lo enviará para todas las solicitudes posteriores hasta que la cookie caduque. express-session leerá esa cookie y adjuntará el objeto de sesión correspondiente como req.session .

Probando la sesión

passport.authenticate(''local'') es para autenticar las credenciales de usuario del cuerpo de POST. Debe usar esto solo para la ruta de inicio de sesión.

Pero para verificar si el usuario está autenticado en todas las demás rutas, puede verificar si req.user está definido.

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!'' }); });