自定义redirect在护照

我正在尝试为我的第一个面向公众的节点应用程序设置一个基本的身份validation。 我有两个护照策略:1)Facebook和2)Twitter。 我不打算至less包括一个电子邮件/密码系统,直到我明白安全的含义。 我已经能够让他们以一种开箱即用的方式工作,并与Mongoose绑定,以创build新的用户。

我现在想要从事重复社交帐号用户的工作。 所以每当一个新用户通过Twitter身份validation进入,我想redirect到一个收集电子邮件的页面。 我保存作为会话variables返回的令牌和configuration文件对象,并将该表单作为隐藏字段提交时,将在该页面上重用它们。

但是我不明白如何使用Passport来实现这个方面。 这里是我到目前为止的代码,我正在试图对每个部分进行评论。 本质上我正在检查如果叽叽喳喳用户是一个老用户,如果没有我设置会话variables,我将在/ addemail页面上重用,初始化用户对象(以便序列化,反序列化function有某些行动(不知道我明白什么序列化/反序列化实际上)现在,如果用户是一个新的,会话variablesNewTwitterUser是真实的,我检查它在auth /callbackurlredirect用户到适当的页面,但这是行不通的。

//basic modules and setup var express = require('express') , passport = require('passport') , mongoose = require('mongoose') , http = require('http') , util = require('util') , TwitterStrategy = require('passport-twitter').Strategy , FacebookStrategy = require('passport-facebook').Strategy , path = require('path'); var app = express(); //Mongodb setup var Schema = mongoose.Schema; var ObjectId = Schema.ObjectId; var UserSchema = new Schema({ provider: String, uid: String, fb_uid: String, twitter_uid: String, name: String, first_name: String, gender: String, fb_username: String, twitter_username: String, profile_pic: String, email: String, location: String, birthday: String, created: {type: Date, default: Date.now} }); var User = mongoose.model('User', UserSchema); mongoose.connect('MongoHQ db connection here')' //User Authentication - Twitter passport.use(new TwitterStrategy({ consumerKey: 'KEY', consumerSecret : 'SECRET', callbackURL: "CALLBACKURL", passReqToCallback: true }, function(req, token, tokenSecret, profile, done){ User.findOne({twitter_uid: profile.id}, function(err, user){ if (err) { console.log('this is an error 1' + err); return done(err);} if(user){ console.log('this user' + user); done(null, user); } else { console.log('this is a new user'); req.session.token = token; req.session.tokenSecret = tokenSecret; req.session.profile = profile; req.session.newtwitteruser = true; var user = new User(); user.uid = profile.id; done(null, user); /* This part is commented and is the default code I had if I needed to simply create a Twitter User right here. var user = new User(); user.provider = profile.provider; user.uid = profile.id; user.twitter_uid = profile.id; user.name = profile.displayName; user.first_name = profile.displayName[0]; user.twitter_username = profile._json.screen_name; user.profile_pic = profile._json.profile_image_url; user.location = profile._json.location; user.save(function(err){ if(err) {throw err;} else {done(null, user);} });*/ } }); } )); //User Authentication - Facebook passport.use(new FacebookStrategy({ clientID: 'ID', clientSecret: 'SECRET', callbackURL: "URL" }, function(accessToken, refreshToken, profile, done){ User.findOne({fb_uid: profile.id}, function(err, user){ if (err) {return done(err);} if(user){ done(null, user); } else { var user = new User(); user.provider = profile.provider; user.uid = profile.id; user.fb_uid = profile.id; user.name = profile.displayName; user.first_name = profile._json.first_name; user.gender = profile._json.gender; user.fb_username = profile._json.username; user.profile_pic = 'https://graph.facebook.com/' + profile.id + '/picture'; user.email = profile._json.email; user.location = profile._json.location.name; user.birthday = profile._json.birthday; user.save(function(err){ if(err) {throw err;} else {done(null, user);} }); } }) } )); passport.serializeUser(function(user, done) { done(null, user.uid); }); passport.deserializeUser(function(uid, done) { User.findOne({uid: uid}, function (err, user) { done(err, user); }); }); //app configurations app.configure(function(){ app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.cookieParser("freecookie")); app.use(express.session({secret:"freecookie"})); app.use(express.static(path.join(__dirname, 'public'))); app.use(express.errorHandler()); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); }); //Basic Routing app.get('/', function(req, res){ res.render('home', {title: 'App Title', user: req.user}); }); app.get('/auth/twitter', passport.authenticate('twitter')); app.get('/auth/twitter/callback', passport.authenticate('twitter', {failureRedirect: '/login' }), function(req, res) { if (req.session.newtwitteruser){ res.redirect('/addemail');} else {res.redirect('/');} }); app.get('/addemail', function(req, res){ if (req.session.newtwitteruser){ res.render('email', {title: 'Add your Email'});} else {res.redirect('/');} }); app.get('/auth/facebook', passport.authenticate('facebook', {scope: ['email', 'user_location', 'user_birthday'] })); app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/', failureRedirect: '/login' })); app.get('/logout', function(req, res){ req.logout(); res.redirect('/'); }); //create the server var server = http.createServer(app); server.listen(app.get('port')); //Checks if a request is authenticated function ensureAuthenticated(req, res, next) { if (req.isAuthenticated()) { return next(); } res.redirect('/login') } 

我会首先redirect成功的login到你的twitter路由中的addemail函数:

  app.get('/auth/twitter', passport.authenticate('twitter')); app.get('/auth/twitter/callback', passport.authenticate('twitter', { successRedirect: '/addemail', failureRedirect: '/' })); 

然后,在你的addemail函数中,我会检查他们是否已经有一封邮件,之后你可以将它们redirect到适当的位置。

  app.get('/addemail', function(req, res){ if (req.user.email){ res.render('email', {title: 'Add your Email'});} else {res.redirect('/');} });