使用Express将额外数据包含到Passport中间件中

问题描述:

用户从另一个应用程序中访问我的网络路由并使用以下格式生成的链接:/auth/steam/:id/:token,其中:id:token不是此Passport中间件所必需的。他们只是我想跟踪的参数。使用Express将额外数据包含到Passport中间件中

当用户成功进行身份验证时,我想要从初始Web请求访问这些值/auth/steam/。我目前的路线是这样的:

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

是否有可能保留的数据与请求到返回路线等一起在那里我注意到我想使用的值?我正在考虑使用会话,但希望避免这种情况。

谢谢!

更新:

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

/auth/steam/return到达回来的时候,会议已被更新从OpenID的请求新的会话的问题:我用express-session将数据添加到会话像这样试过。我的数据不再存在。

+0

我的意思是...如果你重定向,如果它们存在,你不能只是将所述参数与重定向一起传递吗? –

+0

(1)您的会话更新中的lambda函数中的params是否应该为(req,res)=> ...请求是第一个参数,而不是响应? (2)关于参数的传递。 OpenID(如指定的)必须通过以及发送到auth端点的附加/未知查询参数直到返回回调。如果蒸汽实施了他们的后端兼容,你应该添加params到auth req,并且他们应该返回返回路线 –

+0

如果你想尝试基于cookie的认证 http://*.com/questions/38158386/implement -cookie-based-authentication-in-node-js-with-passport 希望它能起作用! –

因为Steam有自己的OpenID策略(https://github.com/liamcurry/passport-steam),所以显然不需要自定义登录策略。

使用会话可能是您尝试的方式,我相信您可以对您的'/auth/steam/:id/:token'路线进行一些调整以使其工作。我提供了一个例子,将您的passport.authenticate('steam')调用的顺序与您的其他回调切换(自从passport.authenticate()将重定向您之后永远不会到达),使用express的中间件next()函数,并且包括req.session.save(),它实际上保存了会话回到您正在使用的商店(文档https://github.com/expressjs/session)。让我知道如果使用以下作为你的新路线不会保存会话的discord_id和令牌属性,当你回到'/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')); 
+0

这正是我所寻找的。谢谢!很棒。你能解释为什么你将回调传递给'req.session.save()'吗? –

+0

这只是允许您支持处理错误,如果保存会话失败,无论出于何种原因。你在技术上不需要传递'next'作为回调,并且可以在req.session.save()之后调用它,而不用将回调传递给save(),但是从技术上讲,你的会话可能无法保存,你不会知道关于它,直到你回到你的返回路线。更多关于快速错误处理的信息,请访问:https://expressjs.com/en/guide/error-handling.html –

+0

我已经厌倦了您的解决方案,但是回调路由中的会话仍然是'undefined'。你能提供一个完整的例子和你正在使用的'express-session'配置吗? – guest459473

许多人使用express的session module来完成这项任务。

一旦会话安装,你可以简单地做 req.session.token = req.params.token; ,然后在其他的处理程序与req.session.token

检索它也可以分配属性护照实例,但是这是一个坏主意。

+0

我放置了我的第一条路线(在将req和res参数添加到回调后)中推荐的内容,然后尝试登录响应处理程序。这些值是未定义的,它看起来像整个会话被它到达返回处理程序的时间覆盖。 –

如果我正确理解您的问题,则需要实施自定义登录策略。这可以通过改变策略来获得策略回调中的req参数:

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

     })); 

然后您可以访问请求中的info对象。这里是你会使用排序功能的例子:

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

,这可以定制排序的功能,你正在寻找实现。如果您使用自定义回调,则需要手动调用req.login函数,但这样可以更多地控制要实现的功能。