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

48

这是我针对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帐户关联起来。

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

谢谢。

3个回答

97

2
成功地将请求对象传递给策略函数,但我无法在数据库回调中使用它(在我的情况下是使用CouchDB的nano)。除了回调之外,所有信息都会丢失。您有任何想法如何通过这些方式获取请求对象吗? - user673046

20

试一试。

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

User是一个mongoose模型,我将用户保存在数据库中。


3
最佳解决方案(因为我不需要重构代码来创建FbStratey的每个请求),谢谢!我认为应该将此标记为正确答案。回答问题“如何实际支持在处理程序函数中获取'req'参数”的主要代码是这里,添加第四个JSON参数,然后查看您现在可以在函数签名中拥有'req'参数:... passReqToCallback: true },function(req,accessToken,refreshToken,profile,done){ - Gene Bo
谢谢,我很高兴你觉得它有用。 - NarendraSoni
req.login和done(null, newUser)是多余的。done(null, newUser)会记录用户登录。 - Tim Hardy

16

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

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

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();
    };
}
使用这个,你将能够在你的验证处理程序中访问请求。

3
另请参阅:https://dev59.com/Dmgt5IYBdhLWcg3w0w3B使用PassportJS,如何向本地认证添加附加表单字段?请翻译以上内容。 - ragamufin
passport是否用新的FacebookStrategy替换了旧的FacebookStrategy - Ishaan Taylor
这对我来说是一个有用的解决方案,因为我想在生成callbackURL参数时使用req.protocolreq.get('host') - Jason Roman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接