Un usuario llega a mi ruta web desde otra aplicación con un enlace que se generó de esta forma: /auth/steam/:id/:token
, donde :id
y :token
no son necesarios para este middleware de Passport. Son solo parámetros de los que quiero hacer un seguimiento.
Cuando el usuario se autentica con éxito, quiero tener acceso a estos valores desde la solicitud web inicial a /auth/steam/
. Mis rutas actualmente se ven así:
this.app.get('/auth/steam/:id/:token', passport.authenticate('steam'), () => { }); this.app.get('/auth/steam/return', passport.authenticate('steam', { failureRedirect: '/login' }), (req, res) => { // Would like access to id and token here res.render('index'); });
¿Es posible mantener los datos junto con la solicitud en la ruta de retorno, etc. donde anoté que quiero usar los valores? Estaba pensando en usar una sesión, pero esperaba evitar eso.
¡Gracias!
Actualización: he intentado usar express-session
para agregar datos a la sesión de esta manera:
this.app.get('/auth/steam/:id/:token', passport.authenticate('steam'), (res, req) => { req.session.discord_id = req.params.id; req.session.token = req.params.token; this.logger.info('Redirecting to Steam'); }); this.app.get('/auth/steam/return', passport.authenticate('steam', { failureRedirect: '/login' }), (req, res) => { console.log('session', req.session.token); res.redirect('/'); });
El problema es que al regresar a /auth/steam/return
, la sesión se ha actualizado con la nueva sesión de la solicitud de OpenID. Mis datos ya no están.
Obviamente, no desea una estrategia de inicio de sesión personalizada ya que Steam tiene su propia estrategia OpenID ( https://github.com/liamcurry/passport-steam ).
Usar sesiones es probablemente el camino a seguir como lo ha intentado, y creo que puede hacer un par de ajustes a su ruta '/auth/steam/:id/:token'
para que funcione. Proporcioné un ejemplo que cambia el orden de su llamada de passport.authenticate('steam')
con su otra devolución de llamada (que nunca llegaría ya que el pasaporte. autenticar () lo redirigiría), usa la función de middleware next()
de express, y incluye un req.session.save()
, que en realidad guarda la sesión en la tienda que está utilizando (documentación en https://github.com/expressjs/session ). Avísame si usar lo siguiente como tu nueva ruta no guarda el discord_id de la sesión y las propiedades del token cuando regreses a '/auth/steam/return'
this.app.get('/auth/steam/:id/:token', (req, res, next) => { req.session.discord_id = req.params.id; req.session.token = req.params.token; this.logger.info('Redirecting to Steam'); req.session.save(next); }, passport.authenticate('steam'));
Si entiendo su pregunta correctamente, debe implementar una estrategia de inicio de sesión personalizada. Esto se puede hacer cambiando su estrategia para obtener los parámetros requeridos dentro de la devolución de llamada de la estrategia:
passport.use('steam', new LocalStrategy({ usernameField: 'email', passwordField: 'password', passReqToCallback: true }, function(req, email, password, done) { //Do your authentication here /**Some Authentication Logic **/ //Get Parameters from the request object... var id = req.params.id; var token = req.params.token var info = {id:id,token:token}; return done(error,user,info); }); }));
Y luego puede acceder al objeto de información en la solicitud. Aquí hay un ejemplo del tipo de función que usaría:
function loginUser(req, res, next) { passport.authenticate('steam', function(err, user, info) { //custom callback requires you to login // your custom variables are in the info object req.login(user, loginErr => { if (!loginErr) { return res.status(200).json({ success: true, err: null, message: 'Logged in correctly!', id: info.id, token: info.token }); } else return res.status(401).json({ success: false, message: 'Unable to login!' }); }); })(req, res, next); }
Una vez más, esto se puede personalizar según el tipo de funcionalidad que desee implementar. Si usa una devolución de llamada personalizada, debe llamar a la función req.login manualmente, pero esto le da mucho más control sobre el tipo de función que está tratando de implementar.
Mucha gente usa el módulo de sesión de Express para esta tarea.
Una vez que se instala la sesión, simplemente puede hacer req.session.token = req.params.token;
y luego en su otro controlador recupérelo con req.session.token
También puede asignar propiedades a la instancia del pasaporte, pero es una mala idea.