在 Passport 策略回调中获取请求对象

Posted

技术标签:

【中文标题】在 Passport 策略回调中获取请求对象【英文标题】:Get request object in Passport strategy callback 【发布时间】:2013-12-18 20:49:35 【问题描述】:

这是我对护照-facebook 策略的配置:

    passport.use(new FacebookStrategy(
        clientID: ".....",
        clientSecret: ".....",
        callbackURL: "http://localhost:1337/register/facebook/callback",
    ,
    facebookVerificationHandler
    ));

这里是 facebookVerificationHandler:

var facebookVerificationHandler = function (accessToken, refreshToken, profile, done)  
    process.nextTick(function ()     
        .......
    );    
;

有没有办法在 facebookVerificationHandler 中访问请求对象?

用户使用 LocalStrategy 注册到我的网站,然后他们将能够添加他们的社交帐户并将这些帐户与他们的本地帐户相关联。当调用上面的回调时,当前登录的用户已经在 req.user 中可用,所以我需要访问 req 以将用户与 facebook 帐户关联。

这是实现它的正确方法还是我应该考虑另一种方法?

谢谢。

【问题讨论】:

【参考方案1】:

有一个passReqToCallback 选项,详情请参阅本页底部:http://passportjs.org/guide/authorize/

【讨论】:

很好地将请求对象获取到策略函数,但我无法在数据库回调中使用它(在我的情况下,它是带有 CouchDB 的 nano)。除了回调,所有信息都丢失了。您是否也知道如何将请求对象传递给这些对象?【参考方案2】:

试试这个。

exports.facebookStrategy = new FacebookStrategy(
        clientID: '.....',
        clientSecret: '...',
        callbackURL: 'http://localhost:3000/auth/facebook/callback',
        passReqToCallback: true
    ,function(req,accessToken,refreshToken,profile,done)
        User.findOne(
                'facebook.id' : profile.id
            ,function(err,user)
            if(err)
                done(err);
            
            if(user)
                req.login(user,function(err)
                    if(err)
                        return next(err);
                    
                    return done(null,user);
                );
            else
                var newUser = new User();
                newUser.facebook.id = profile.id;
                newUser.facebook.name = profile.displayName;
                newUser.facebook.token = profile.token;
                newUser.save(function(err)
                    if(err)
                        throw(err);
                    
                    req.login(newUser,function(err)
                        if(err)
                            return next(err);
                        
                        return done(null,newUser);
                    );
                );
            
        );
    
);

用户是猫鼬模型,我将用户保存在数据库中。

【讨论】:

最佳解决方案(因为我不必重构以在每个请求上创建 FbStratey),谢谢!我认为这应该被标记为正确答案。回答这个问题的主要代码——如何真正支持在处理函数中获取“req”参数——是这里的这一部分,添加第 4 个 JSON 参数,然后看到你现在可以在函数签名中拥有“req”参数: .... passReqToCallback: true ,function(req,accessToken,refreshToken,profile,done) 谢谢,我很高兴你发现它有用。 req.login 和 done(null, newUser) 是多余的。 done(null, newUser) 使用户登录。【参考方案3】:

因此,我通常不会在应用程序启动时设置策略,而是在有请求时设置策略。例如:

app.get(
    '/facebook/login'
    ,passport_setup_strategy()
    ,passport.authenticate()
    ,redirect_home()
);

var isStrategySetup = false;
var passport_setup_strategy = function()
    return function(req, res, next)
        if(!isStrategySetup)

            passport.use(new FacebookStrategy(
                    clientID: ".....",
                    clientSecret: ".....",
                    callbackURL: "http://localhost:1337/register/facebook/callback",
                ,
                function (accessToken, refreshToken, profile, done)  
                    process.nextTick(function ()     
                        // here you can access 'req'
                        .......
                    );    
                
            ));

            isStrategySetup = true;

        

        next();
    ;

使用它,您将可以访问验证处理程序中的请求。

【讨论】:

另见:***.com/questions/11784233/… passport 是否用新的FacebookStrategy 替换旧的FacebookStrategy 这对我来说是一个有用的解决方案,因为我想使用req.protocolreq.get('host') 来生成callbackURL 参数

以上是关于在 Passport 策略回调中获取请求对象的主要内容,如果未能解决你的问题,请参考以下文章

Passport.js本地策略如何保护路线

Passportjs 成功回调从未被调用

如何在 Angular 客户端中处理 passport-facebook 回调?

Passport JWT 策略没有被调用

从回调中访问 jwtFromRequest

nodejs - passport.use 回调返回 dataValues 和 _previousDataValues 而不是普通对象