2012-11-03 94 views
6

我想爲我的第一個面向公衆的節點應用程序設置基本身份驗證。我有兩個護照策略:1)用於Facebook和2)用於Twitter。至少現在我不打算包含電子郵件/密碼系統,直到我瞭解安全含義。 我已經能夠讓他們以開箱即用的方式工作,並在Mongoose中建立新用戶。Passport自定義重定向

我現在想要從事重複社交帳戶用戶的工作。所以每當新用戶通過Twitter身份驗證進入時,我想將他們重定向到收集電子郵件的頁面。我將保存作爲會話變量返回的令牌和配置文件對象,並在將該窗體作爲隱藏字段提交時,在該頁面上重新使用它們。

但是我不明白如何使用Passport實現這個方面。這裏是我迄今爲止的代碼,並對我正在試圖對每個部分進行評論。基本上我正在檢查如果Twitter用戶是一箇舊用戶,如果沒有我設置會重新使用/ addemail頁面,初始化用戶對象的會話變量(以便Serialize,Deserialize函數有行動的東西(不知道我明白什麼序列化/反序列化實際上做)現在,如果用戶是一個新的,會話變量NewTwitterUser是真實的,我檢查它在auth /回調url重定向用戶到適當的頁面,但這是行不通的

//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') 
} 

回答

6

我會先成功登錄重定向到您的addemail功能你的Twitter路線內:

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

釷en,在你的addemail函數中,我會檢查他們是否已經有一封電子郵件,之後你可以將它們重定向到適當的位置。

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