我有三种用户:
我还有3个不同的db / collection
每种类型的用户都有不同的登录链接。
现在让我们来看看代码
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: '/' }));
这是我的表格
<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>
数据传递给登录流程吗?所以我们可以在TwitterStrategy中读取输入数据,并保存到数据库中
2. 我们可以从登录网址(auth / c / twitter)获取“c”并将其传递给TwitterStrategy吗?所以我们可以简单地检查不同的db / collection并更改查询。
答案 0 :(得分:2)
我们的想法是在将用户重定向到Twitter以进行身份验证之前存储您的值,并在用户回来后重新使用这些值。
OAuth2包含scope参数,完全适合这种情况。不幸的是,TwitterStrategy基于OAuth1。但我们可以解决它!
下一个技巧是在创建用户时。 在声明策略时不应该这样做(因为你无法访问输入数据),但是稍后,在最后一次身份验证回调中 see here the callback arguments
宣布您的策略:
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);
}));
声明您的身份验证网址时(重复/ 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() {});
然后在声明回调时:
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)
});