2012-03-27 24 views
17

Estoy usando la estrategia Google Express de Express y Passport y me gustaría establecer returnURL en cada solicitud de autenticación para poder regresar a la página que inició esa autenticación.ReturnUrl personalizado en Node.js Estrategia de Google Passport

La situación es que tengo una aplicación de diapositivas HTML5 con Node.js backend (y con cosas sociales y editor y Portal y extensiones ... https://github.com/bubersson/humla) y quiero poder iniciar sesión en algunas diapositivas (a través del menú de diapositivas ...) pero luego quiero que regrese a la misma diapositiva fácilmente.

Entonces, ¿necesitaría algo como esto?

app.get('/auth/google', function(req,res) { 
    var cust = "http://localhost:1338/"+req.params.xxx; 
    passport.authenticate('google', returnURL:cust, function ... 
} 

He leído la guía de Passport, pero todavía no sé cómo hacerlo. Sé que esto no sería seguro, pero ¿cómo podría hacerlo?

¿O cómo puedo hacer que la aplicación regrese a la página desde donde se inició el inicio de sesión? ¿O hay una manera de hacer la autenticación de OpenID usando AJAX (y aún así poder usar el pasaporte también)?

Respuesta

24

He cuenta de esto para mi aplicaciones de autenticación de Twitter, estoy seguro de que el GoogleStrategy es bastante similar. Pruebe con una variante de este:

Suponiendo que haya definido la ruta para la devolución de llamada desde el servicio de autenticación como tal (de la guía pasaporte):

app.get('/auth/twitter/callback', 
    passport.authenticate('twitter', { 
     successRedirect: authenticationRedirect(req, '/account') 
    , failureRedirect: '/' 
    }) 
); 

acaba de cambiar ese bloque a esto:

app.get('/auth/twitter/callback', function(req, res, next){ 
    passport.authenticate('twitter', function(err, user, info){ 
    // This is the default destination upon successful login. 
    var redirectUrl = '/account'; 

    if (err) { return next(err); } 
    if (!user) { return res.redirect('/'); } 

    // If we have previously stored a redirectUrl, use that, 
    // otherwise, use the default. 
    if (req.session.redirectUrl) { 
     redirectUrl = req.session.redirectUrl; 
     req.session.redirectUrl = null; 
    } 
    req.logIn(user, function(err){ 
     if (err) { return next(err); } 
    }); 
    res.redirect(redirectUrl); 
    })(req, res, next); 
}); 

Ahora, defina su middleware para rutas autenticados para almacenar la URL original en la sesión de la siguiente manera:

ensureAuthenticated = function (req, res, next) { 
    if (req.isAuthenticated()) { return next(); } 

    // If the user is not authenticated, then we will start the authentication 
    // process. Before we do, let's store this originally requested URL in the 
    // session so we know where to return the user later. 

    req.session.redirectUrl = req.url; 

    // Resume normal authentication... 

    logger.info('User is not authenticated.'); 
    req.flash("warn", "You must be logged-in to do that."); 
    res.redirect('/'); 
} 

¡Trabajos!

+0

Esto funciona perfectamente, pero en la redirección parece que le faltan los parámetros de hash si el usuario se envía para autenticarse y vuelve. ¿Podría haber alguna manera de mantener esos en la URL al redirigir después de iniciar sesión? http://stackoverflow.com/questions/14124932/passport-js-express-js-forward-user-to-original-destination-after-authenticati – prototype

+0

@ user645715 quizás intente utilizar 'req.session.redirectUrl = req.originalUrl ; 'instead or' req.url' –

+0

funciona como un amuleto, gracias :) – Zub

5

Trate res.redirect('back'); en la devolución de llamada para passport.authenticate

+0

¡Gracias! Aparentemente, la ruta de retorno se establece entre la primera y la segunda solicitud de OpenID. ¡No lo sabía! Gracias – bubersson

+2

Bueno, encontré un problema con esto. Funciona solo si ya estoy conectado usando Google. Si el pasaporte redirecciona a la página de Google y luego regresa a mi sitio, la ruta de la "página" se pierde. ¿Hay alguna otra manera de obligarlo a regresar de Google a mi ubicación (la página desde donde se inició el inicio de sesión)? – bubersson

+0

@bubersson, necesitaría utilizar un enfoque más proactivo como el de la primera respuesta, para eso, si entiendo correctamente. – matanster

3

De acuerdo con el autor, esto no es posible con las estrategias de OpenID. Hemos conseguido actualizar estos dinámicamente accediendo directamente a las variables:

app.get('/auth/google', function(req, res, next) { 
    passport._strategies['google']._relyingParty.returnUrl = 'http://localhost:3000/test'; 
    passport._strategies['google']._relyingParty.realm = 'http://localhost:3000'; 
    passport.authenticate('google')(req, res, next); 
}); 
13

Dondequiera que usted tiene su botón de inicio de sesión, agregue URL actual de la solicitud como un parámetro de consulta (ajustamos por cualquier sistema de plantillas que usa):

<a href='/auth/google?redirect=<%= req.url %>'>Log In</a> 

a continuación, añadir middleware para su controlador GET /auth/google que almacena este valor en req.session:

app.get('/auth/google', function(req, res, next) { 
    req.session.redirect = req.query.redirect; 
    next(); 
}, passport.authenticate('google')); 

Finalmente, en su controlador de devolución de llamada, redirija a la URL almacenada en la sesión:

app.get('/auth/google/callback', passport.authenticate('google', 
    failureRedirect: '/' 
), function (req, res) { 
    res.redirect(req.session.redirect || '/'); 
    delete req.session.redirect; 
}); 
+0

¿Es posible hacer esto sin sesiones? – nahtnam

Cuestiones relacionadas