使用passportjs完成本地用户身份验证后,将Twitter帐户与Passportjs链接

时间:2015-12-28 14:32:03

标签: javascript node.js express twitter passport.js

我只想在有用户之后链接推特账号。

首先我有一个像这样的router.js

// GET Registration Page
router.get('/signup', function(req, res){
    res.render('register',{noty: req.flash('message')});
});

// Handle Registration POST 
router.post('/signup', passport.authenticate('signup', {
    successRedirect: '/connect_twitter',
    failureRedirect: '/signup',
    failureFlash : true  
}));  

/* GET Twitter Auth*/
router.get('/login/twitter', passport.authenticate('twitter'));
router.get('/login/twitter/return', 
    passport.authenticate('twitter', { failureRedirect: '/' }),
    function(req, res) {
        res.redirect('/home');
});

如果成功,我将"/connect_twitter"重定向到req.user != null ,那是当前的用户。在"/connect_twitter"一个带有按钮的重定向推特。

当Twitter返回用户的令牌时,我使用此策略

passport.use(new TwitterStrategy({
    consumerKey: config.twitter.consumer_key,
    consumerSecret: config.twitter.consumer_secret,
    callbackURL: config.tw_callback 
  },
  function(token, tokenSecret, profile, cb) {
    // In this example, the user's Twitter profile is supplied as the user
    // record.  In a production-quality application, the Twitter profile should
    console.log(profile);
        findOrCreateUser = function(){
            // find a user in Mongo with provided username
            User.findOne({'tw_user_id': profile.id}, function(err, user) {
                // In case of any error, return using the done method
                if (err){
                    return cb(err);
                }
                // already exists
                if (user) {
                    user.tw_token = token;
                    user.tw_token_secret = tokenSecret;
                    user.save(function(err){
                        if (err) {
                            throw err;
                        } 
                        console.log("User Updating successfull !");
                    })
                    return cb(null, user);
                } else {
                    // create the user
                    var newUser = new User();
                    // set the user's local credentials
                    newUser.password = createHash(token);
                    newUser.username = profile.username;
                    newUser.email = null; 
                    newUser.tw_token = token;
                    newUser.tw_user_id = profile.id;
                    newUser.tw_token_secret = tokenSecret;
                    // save the user
                    newUser.save(function(err) {
                        if (err){
                            console.log('Error in Saving user: '+err);  
                            throw err;  
                        }
                        console.log('User Registration succesful');    
                        return cb(null, newUser);
                    });
                }
            });
        };

        process.nextTick(findOrCreateUser);

  }));

问题是如何在此函数function(token, tokenSecret, profile, cb)中访问current_user或有关当前用户的任何内容? 我认为,如果我访问它,我将当前用户与这些令牌链接。

是否有更好的(任何)方式将Twitter与当前用户联系起来?

提前致谢..

2 个答案:

答案 0 :(得分:4)

passportjs docs

  

验证回叫中的关联

     

上述方法的一个缺点是它需要两个相同策略和支持路径的实例。

     

要避免这种情况,请将策略的passReqToCallback选项设置为true。启用此选项后,req将作为验证回调的第一个参数传递。

passport.use(new TwitterStrategy({
    consumerKey: TWITTER_CONSUMER_KEY,
    consumerSecret: TWITTER_CONSUMER_SECRET,
    callbackURL: "http://www.example.com/auth/twitter/callback",
    passReqToCallback: true
  },
  function(req, token, tokenSecret, profile, done) {
    if (!req.user) {
      // Not logged-in. Authenticate based on Twitter account.
    } else {
      // Logged in. Associate Twitter account with user.  Preserve the login
      // state by supplying the existing user after association.
      // return done(null, req.user);
    }
  }
));
  

req作为参数传递,验证回调可以使用请求的状态来定制身份验证过程,使用单个策略实例和路由集处理身份验证和授权。例如,如果用户已经登录,则新的"已连接"帐户可以关联。还可以使用req上设置的任何其他特定于应用程序的属性,包括req.session

顺便说一下,您可以处理当前用户及其数据,以链接任何社交策略,包括Twitter。

答案 1 :(得分:1)

您可以通过两种方式实现这一目标:

  1. 您可以从Twitter响应中获取用户电子邮件,并将其与用户在数据库中使用相同的电子邮件进行匹配,而不是尝试在Twitter策略中获取req.user。通常,您无法直接从Twitter API获取电子邮件,您需要填写请求表单here以获得提升的访问权限。接受请求后,您将能够从Twitter API收到电子邮件。

  2. 在Twitter登录后,您可以将用户Twitter个人资料信息保存在临时表中,并重定向/user/do_login?twitter_profile_id=<user_twitter_profile_id_fetched_from_twitter_response>之类的页面。当您重定向到/user/do_login时,您将能够访问req.user,并且您还将拥有用户个人资料ID。在此操作中,您可以从临时表中获取用户配置文件信息,并将其与req.user合并。顺便说一句,我假设你正在使用存储的会话。