node.js authentication redirect express passport.js

Redireccionando a la página anterior después de la autenticación en node.js usando passport.js



authentication redirect (7)

Estoy intentando establecer un mecanismo de inicio de sesión usando node.js, express y passport.js. El inicio de sesión funciona bastante bien, también las sesiones se guardan muy bien con redis, pero tengo algunos problemas para redirigir al usuario a donde comenzó antes de que se le pida que autentique.

por ejemplo, el usuario sigue el enlace http://localhost:3000/hidden luego se redirige a http://localhost:3000/login pero luego quiero que se lo redirija de nuevo a http://localhost:3000/hidden .

El objetivo de esto es que si el usuario accede aleatoriamente a una página en la que necesita iniciar sesión primero, se le redirigirá al sitio de inicio de sesión proporcionando sus credenciales y luego será redirigido al sitio al que previamente intentó acceder.

Aquí está mi entrada

app.post(''/login'', function (req, res, next) { passport.authenticate(''local'', function (err, user, info) { if (err) { return next(err) } else if (!user) { console.log(''message: '' + info.message); return res.redirect(''/login'') } else { req.logIn(user, function (err) { if (err) { return next(err); } return next(); // <-? Is this line right? }); } })(req, res, next); });

y aquí mi método garantizado autenticado

function ensureAuthenticated (req, res, next) { if (req.isAuthenticated()) { return next(); } res.redirect(''/login''); }

que se engancha en la página /hidden

app.get(''/hidden'', ensureAuthenticated, function(req, res){ res.render(''hidden'', { title: ''hidden page'' }); });

La salida html para el sitio de inicio de sesión es bastante simple

<form method="post" action="/login"> <div id="username"> <label>Username:</label> <input type="text" value="bob" name="username"> </div> <div id="password"> <label>Password:</label> <input type="password" value="secret" name="password"> </div> <div id="info"></div> <div id="submit"> <input type="submit" value="submit"> </div> </form>


Eche un vistazo a connect-ensure-login , que funciona junto con Passport para hacer exactamente lo que quiere.


En su método ensureAuthenticated , guarde la URL de retorno en la sesión de esta manera:

... req.session.returnTo = req.path; res.redirect(''/login''); ...

Luego puede actualizar su pasaporte. Autenticar la ruta a algo como:

app.get(''/auth/google/return'', passport.authenticate(''google''), function(req, res) { res.redirect(req.session.returnTo || ''/''); delete req.session.returnTo; });



Las respuestas de @chovy y @linuxdan tienen un error al no borrar la session.returnTo si el usuario va a otra página después de redirigir el inicio de sesión (eso no requiere autenticación) e inicia sesión allí. Así que agrega este código a sus implementaciones:

// clear session.returnTo if user goes to another page after redirect to login app.use(function(req, res, next) { if (req.path != ''/login'' && req.session.returnTo) { delete req.session.returnTo } next() })

Si realiza algunas solicitudes ajax desde la página de inicio de sesión, también puede excluirlas.

Otro enfoque es utilizar flash para ensureAuthenticated

req.flash(''redirectTo'', req.path) res.redirect(''/login'')

Y luego en GET login

res.render(''login'', { redirectTo: req.flash(''redirectTo'') })

A la vista, agregue el campo oculto al formulario de inicio de sesión (ejemplo en jade)

if (redirectTo != '''') input(type="hidden" name="redirectTo" value="#{redirectTo}")

En el inicio de sesión POST

res.redirect(req.body.redirectTo || ''/'')

Observe que redirectTo se borrará después de que GET inicie sesión con él.


Mi forma de hacer las cosas:

const isAuthenticated = (req, res, next) => { if (req.isAuthenticated()) { return next() } res.redirect( `/login?origin=${req.originalUrl}` ) };

GET / controlador de inicio de sesión

if( req.query.origin ) req.session.returnTo = req.query.origin else req.session.returnTo = req.header(''Referer'') res.render(''account/login'')

Controlador de POST / inicio de sesión :

let returnTo = ''/'' if (req.session.returnTo) { returnTo = req.session.returnTo delete req.session.returnTo } res.redirect(returnTo);

Controlador POST / logout (no estoy seguro de si hay un 100% de aceptación, los comentarios son bienvenidos):

req.logout(); res.redirect(req.header(''Referer'') || ''/''); if (req.session.returnTo) { delete req.session.returnTo }

Borrar returnTo middleware (borra returnTo de la sesión en cualquier ruta excepto en auth routes - para mí son / login y / auth /: provider):

String.prototype.startsWith = function(needle) { return(this.indexOf(needle) == 0) } app.use(function(req, res, next) { if ( !(req.path == ''/login'' || req.path.startsWith(''/auth/'')) && req.session.returnTo) { delete req.session.returnTo } next() })

Este enfoque tiene dos características :

  • puedes proteger algunas rutas con middleware autenticado ;
  • en cualquier página puede simplemente hacer clic en la URL de inicio de sesión y, después de iniciar sesión, volver a esa página;

No sé sobre el pasaporte, pero así es como lo hago:

Tengo un middleware que uso con app.get(''/account'', auth.restrict, routes.account) que establece redirectTo en la sesión ... luego me redirecciona a / login

auth.restrict = function(req, res, next){ if (!req.session.userid) { req.session.redirectTo = ''/account''; res.redirect(''/login''); } else { next(); } };

Luego en routes.login.post hago lo siguiente:

var redirectTo = req.session.redirectTo ? req.session.redirectTo : ''/''; delete req.session.redirectTo; // is authenticated ? res.redirect(redirectTo);


Si está utilizando connect-ensure-login hay una forma integrada muy fácil de hacerlo con Passport utilizando el parámetro successReturnToOrRedirect . Cuando se usa, el pasaporte lo enviará de regreso a la URL solicitada originalmente o se recurrirá a la URL que proporcione.

router.post(''/login'', passport.authenticate(''local'', { successReturnToOrRedirect: ''/user/me'', failureRedirect: ''/user/login'', failureFlash: true }));

https://github.com/jaredhanson/connect-ensure-login#log-in-and-return-to