简体   繁体   English

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

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

I just want to link twitter account after there is still user. 我只想在有用户之后链接Twitter帐户。

Firstly i have a router.js like that 首先,我有一个像这样的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');
});

if its success, i redirected "/connect_twitter" with req.user != null , that is current user. 如果成功,我将"/connect_twitter"重定向到req.user != null ,即当前用户。 In the "/connect_twitter" a redirect twitter with a button. "/connect_twitter" ,使用按钮重定向推特。

When twitter return user's tokens, i use this strategy 当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);

  }));

The problem is how to access current_user or anything about the current user in this function function(token, tokenSecret, profile, cb) ? 问题是如何在此函数function(token, tokenSecret, profile, cb)访问current_user或有关当前用户的任何内容? As i think, If i access that, i linked current user with these tokens. 我认为,如果我访问它,我将当前用户与这些令牌链接。

Or 要么

Is there better (any) way to link twitter with the current user ? 是否有更好的(任何)方式将Twitter与当前用户联系起来?

Thanks in advance.. 提前致谢..

In the passportjs docs passportjs文档中

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 . 要避免这种情况,请将策略的passReqToCallback选项设置为true With this option enabled, req will be passed as the first argument to the verify callback. 启用此选项后,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);
    }
  }
));

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. 使用req作为参数传递,验证回调可以使用请求的状态来定制身份验证过程,使用单个策略实例和路由集处理身份验证和授权。 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. 还可以使用在req设置的任何其他特定于应用程序的属性,包括req.session

By the way, you can handle with the current user and its data to link any social strategy including Twitter. 顺便说一句,您可以处理当前用户及其数据以链接任何社交策略,包括Twitter。

You can do that in 2 ways: 你可以用两种方式做到这一点:

  1. Instead of trying to get req.user inside Twitter Strategy, you can get user email fetched from twitter response and match it with user with same email inside database. 您可以从Twitter响应中获取用户电子邮件,并将其与用户在数据库中使用相同的电子邮件进行匹配,而不是尝试在Twitter策略中获取req.user Normally, you cannot get email directly from Twitter API, you need to fill request form here to get elevated access. 通常情况下,你不能直接从Twitter的API获取电子邮件,您需要填写申请表在这里得到提升的访问。 After request accepted, you will be able to get email from Twitter API. 接受请求后,您将能够从Twitter API收到电子邮件。

  2. After twitter login, you can save user twitter profile information inside a temp table and redirect a page like /user/do_login?twitter_profile_id=<user_twitter_profile_id_fetched_from_twitter_response> . 在Twitter登录后,您可以将用户twitter个人资料信息保存在临时表中,并重定向一个页面,如/user/do_login?twitter_profile_id=<user_twitter_profile_id_fetched_from_twitter_response> When you redirect to /user/do_login you will be able to access req.user and also you will have user profile id. 当您重定向到/user/do_login您将能够访问req.user ,并且您将拥有用户配置文件ID。 In this action, you can grab user profile info from temp table and merge it with req.user . 在此操作中,您可以从临时表中获取用户配置文件信息,并将其与req.user合并。 By the way, I assume that, you are using stored session. 顺便说一句,我假设你正在使用存储的会话。

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

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