如何通过TwitterStrategy,PassportJS传递数据?

我有三种用户:

  1. 查看器 (链接login:auth / v / twitter)
  2. 创build者 (链接login:auth / c / twitter)
  3. pipe理员 (链接login:auth / a / twitter)

而且我也有3个不同的数据库/集合

  1. c_viewer
  2. c_creator
  3. C_ADMIN

每种用户都有不同的链接login。

现在让我们来看看代码

var passport = require('passport') ,TwitterStrategy = require('passport-twitter').Strategy; passport.use(new TwitterStrategy({ consumerKey: config.development.tw.consumerKey, consumerSecret: config.development.tw.consumerSecret, callbackURL: config.development.tw.callbackURL }, function(token, tokenSecret, profile, done) { process.nextTick(function(req, res) { var query = User.findOne({ 'twId': profile.id}); query.exec(function(err, oldUser){ if(oldUser) { done(null, oldUser); } else { var newUser = new User(); newUser.twId = profile.id; newUser.twUsername = profile.username; newUser.name = profile.displayName; newUser.avatar = profile.photos[0].value; -> newUser.age = req.body.creator.age; ??? newUser.save(function(err) { if(err) throw err; done(null, newUser); }); }; }); }); })); app.get('/auth/c/twitter', passport.authenticate('twitter'), function(req, res) { var userUrl = req.url; // codes to pass the userUrl to TwitterStrategy }); app.get('/auth/twitter/callback', passportForCreator.authenticate('twitter', { successRedirect: '/dashboard', failureRedirect: '/' })); 

这是我的forms

 <input type="text" name="creator[age]" placeholder="How old are you?"> <a id="si" class="btn" href="/auth/c/twitter">Sign in</a> 

我的问题:

1.我们可以将<input>数据传递给login过程吗? 所以我们可以读取TwitterStrategy中的input数据,并保存到数据库
2.我们可以从loginurl(auth / c / twitter)获得“c”并将其传递给TwitterStrategy? 所以我们可以简单地检查不同的数据库/集合并更改查询。

这个想法是在将用户redirect到Twitter以进行身份​​validation之前存储您的值,并在用户返回时重新使用这些值。

OAuth2包含范围参数,非常适合这种情况。 不幸的是,TwitterStrategy基于OAuth1。 但我们可以解决它!

下一个技巧是关于何时创build用户。 在声明策略时(因为无法访问input数据),您不应该这样做,但是稍后在最后一次身份validationcallback中, 请参阅此处的callback参数 。

宣布你的策略:

 passport.use(new TwitterStrategy({ consumerKey: config.development.tw.consumerKey, consumerSecret: config.development.tw.consumerSecret, callbackURL: config.development.tw.callbackURL }, function(token, tokenSecret, profile, done) { // send profile for further db access done(null, profile); })); 

声明您的身份validationurl时(重复/ twitter和v / twitter):

 // declare states where it's accessible inside the clusre functions var states={}; app.get("/auth/c/twitter", function (req, res, next) { // save here your values: database and input var reqId = "req"+_.uniqueId(); states[reqId] = { database: 'c', age: $('input[name="creator[age]"]').val() }; // creates an unic id for this authentication and stores it. req.session.state = reqId; // in Oauth2, its more like : args.scope = reqId, and args as authenticate() second params passport.authenticate('twitter')(req, res, next) }, function() {}); 

然后在声明callback时:

 app.get("/auth/twitter/callback", function (req, res, next) { var reqId = req.session.state; // reuse your previously saved state var state = states[reqId] passport.authenticate('twitter', function(err, token) { var end = function(err) { // remove session created during authentication req.session.destroy() // authentication failed: you should redirect to the proper error page if (err) { return res.redirect("/"); } // and eventually redirect to success url res.redirect("/dashboard"); } if (err) { return end(err); } // now you can write into database: var query = User.findOne({ 'twId': profile.id}); query.exec(function(err, oldUser){ if(oldUser) { return end() } // here, choose the right database depending on state var newUser = new User(); newUser.twId = profile.id; newUser.twUsername = profile.username; newUser.name = profile.displayName; newUser.avatar = profile.photos[0].value; // reuse the state variable newUser.age = state.age newUser.save(end); }); })(req, res, next) });