简体   繁体   English

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

[英]Including extra data into Passport middleware with Express

A user is coming to my web route from another application with a link that was generated in this form: /auth/steam/:id/:token , where :id and :token are not required for this Passport middleware. 用户从另一个应用程序进入我的Web路由,其中​​包含以这种形式生成的链接: /auth/steam/:id/:token ,其中:id:token不是此Passport中间件所必需的。 They are just parameters I want to keep track of. 它们只是我想要跟踪的参数。

When the user successfully authenticates, I want to have access to these values from the initial web request to /auth/steam/ . 当用户成功进行身份验证时,我希望能够从初始Web请求访问这些值到/auth/steam/ My routes currently look like this: 我的路线目前看起来像这样:

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

Is it possible to keep data along with the request into the return route, etc. where I noted I want to use the values? 是否有可能将数据与请求一起保存到返回路径等,我注意到我想使用这些值? I was thinking of using a session but was hoping to avoid that. 我正在考虑使用会话,但希望避免这种情况。

Thanks! 谢谢!

Update: I've tried using express-session to add data to the session like so: 更新:我尝试使用express-session将数据添加到会话中,如下所示:

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

The problem is when arriving back at /auth/steam/return , the session has been updated with the new session from the OpenID request. 问题是当返回/auth/steam/return ,会话已使用OpenID请求中的新会话进行更新。 My data no longer is there. 我的数据不再存在。

You obviously don't want a custom login strategy since Steam has it's own OpenID strategy ( https://github.com/liamcurry/passport-steam ). 您显然不需要自定义登录策略,因为Steam拥有自己的OpenID策略( https://github.com/liamcurry/passport-steam )。

Using sessions is probably the way to go as you've tried, and I believe you can make a couple tweaks to your '/auth/steam/:id/:token' route to make it work. 使用会话可能就像你尝试过的那样,我相信你可以对你的'/auth/steam/:id/:token'路线进行一些调整以使其工作。 I provided an example that switches the order of your passport.authenticate('steam') call with your other callback (which would never get to since the passport.authenticate() would redirect you), uses express's middleware next() function, and includes a req.session.save() , which actually saves the session back to the store you're using (documentation in https://github.com/expressjs/session ). 我提供了一个示例,用你的其他回调切换你的passport.authenticate('steam')调用的顺序passport.authenticate('steam')由于passport.authenticate()会重定向你,这将永远不会到达),使用express的中间件next()函数,以及包括一个req.session.save() ,它实际上将会话保存回你正在使用的商店( https://github.com/expressjs/session中的文档)。 Let me know if using the following as your new route doesn't save the session's discord_id and token properties when you get back to '/auth/steam/return' 如果您回到'/auth/steam/return' ,请使用以下内容作为新路由,不保存会话的discord_id和令牌属性

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

If I understand your question correctly, you need to implement a custom login strategy. 如果我正确理解您的问题,您需要实施自定义登录策略。 This can be done by changing your strategy to get the req parameters inside the strategy callback: 这可以通过更改策略来获取策略回调中的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);
            });

        }));

And then you can access the info object in the request. 然后您可以访问请求中的info对象。 Here is an example of the sort of function you would use: 以下是您将使用的函数类型的示例:

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

Once again, this can be customized to the sort of functionality you are looking to implement. 再次,这可以根据您要实现的功能进行自定义。 If you use a custom callback, you need to call the req.login function manually, but this gives you a lot more control on the sort of function you are trying to implement. 如果使用自定义回调,则需要手动调用req.login函数,但这样可以更好地控制您尝试实现的函数类型。

Many people use express's session module for this task. 很多人使用express的会话模块来完成这项任务。

Once session is installed you can simply do req.session.token = req.params.token; 安装会话后,您只需执行req.session.token = req.params.token; and then in your other handler retrieve it with req.session.token 然后在你的其他处理程序中使用req.session.token检索它

You can also assign properties to the passport instance, but this is a bad idea. 您也可以为护照实例分配属性,但这不是一个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM