Link 使用 passportjs 完成本地用户身份验证后使用 Passportjs 的 Twitter 帐户

Link Twitter Account with Passportjs after local user auth is completed with passportjs

我只想link twitter账号还有用户

首先我有一个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" 中有一个带有按钮的重定向推特。

当twitterreturn用户的代币,我使用这个策略

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

  }));

问题是如何访问 current_user 或此函数 function(token, tokenSecret, profile, cb) 中有关当前用户的任何信息? 正如我所想,如果我访问它,我 link 使用这些令牌编辑了当前用户。

是否有更好的(任何)方式与当前用户 link 推特?

提前致谢..

您可以通过两种方式做到这一点:

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

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

passportjs docs

Association in Verify Callback

One downside to the approach described above is that it requires two instances of the same strategy and supporting routes.

To avoid this, set the strategy's passReqToCallback option to true. With this option enabled, req will be passed as the first argument to the verify callback.

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

With req passed as an argument, the verify callback can use the state of the request to tailor the authentication process, handling both authentication and authorization using a single strategy instance and set of routes. For example, if a user is already logged in, the newly "connected" account can be associated. Any additional application-specific properties set on req, including req.session, can be used as well.

顺便说一下,您可以将当前用户及其数据处理到 link 包括 Twitter 在内的任何社交策略。