使用passport-google-oauth2与Facebook和Google进行身份validation

我正在尝试使用passport-google-oauth2passport-facebook分别passport-facebook和Google进行身份validation。

我的auth文件夹的项目结构如下所示:

 auth/facebook index.js login.js verifyCallback.js auth/google index.js login.js verifyCallback.js 

auth / google代码如下所示:

 verifyCallback.js var User = require('../../models/user'); module.exports = function(accessToken,refreshToken,profile,done){ function findOrCreateUser(){ console.log(profile); User.findOne({'google.id':profile._json.id},function(err,user){ if(err){ console.log("An error occured when logging in with google"); console.error(err); done(err); } else if(user) { console.log("User exists in google verify callback"); console.log(user); done(null,user); } else{ console.log("Creating a new user in google verify callback"); var payload = { google:{ token:accessToken, email:profile._json.emails[0].value, id:profile._json.id, name:profile._json.displayName } }; console.log(payload); var user = new User(payload); user.save(function(err,user){ if(err) { console.log("Error occured when creating new user with google in verify callback"); console.error(err); done(null); } else console.log("User successfully added with google in verify callback"); done(null,user); }); } }); } process.nextTick(findOrCreateUser); }; 

这是将validationcallback应用于策略的login.js:

  login.js var GoogleStratgy = require('passport-google-oauth2'); var config = require('../config').google; var callback = require('./verifyCallback'); module.exports = function(passport){ passport.use('google',new GoogleStratgy(config,callback)); }; 

index.js的代码如下所示:

 index.js var User = require('../../models/user'); var login = require('./login'); module.exports = function(passport) { var serializeGoogleCallback = function serializeGoogleCallback(user,done){ console.log("Serializing google user"); console.log(user); done(null, user.google.id); }; var deserializeGoogleCallback = function deserializeGoogleCallback(id,done){ console.log("Deserializing google user"); console.log(id); User.findOne({'google.id':id},function(err,user){ if(err) console.log("An error occured while deserializing user"); else console.log(user); done(err,user); }); }; passport.serializeUser(serializeGoogleCallback); passport.deserializeUser(deserializeGoogleCallback); login(passport); }; 

auth / facebook的代码如下所示:

 index.js var User = require('../../models/user'); var login = require('./login'); module.exports = function(passport) { var serializeFacebookCallback = function serializeFacebookCallback(user,done){ console.log("Serializing facebook user"); console.log(user); done(null, user.facebook.id); }; var deserializeFacebookCallback = function deserializeFacebookCallback(id,done){ console.log("Deserializing facebook user"); User.findOne({'facebook.id':id},function(err,user){ if(err) { console.log("Error occured when deserializing user"); } else console.log(user); return done(err,user); }); }; passport.serializeUser(serializeFacebookCallback); passport.deserializeUser(deserializeFacebookCallback); login(passport); }; ---------------------------------------------------------------------------- login.js var config = require('../config'); var FacebookStrategy = require('passport-facebook').Strategy; var verifyCallback = require('./verifyCallback'); module.exports = function(passport){ var fbConf = { clientID: config.facebook.clientId, clientSecret: config.facebook.clientSecret, callbackURL: config.facebook.callbackURL, enableProof: false, }; passport.use('facebook',new FacebookStrategy(fbConf,verifyCallback)); }; ---------------------------------------------------------------------------- verifyCallback.js var User = require('../../models/user'); module.exports = function(accessToken, refreshToken, profile, done) { function findOrCreateUser(){ User.findOne({'facebook.id':profile.id},function(err,user){ if(err) { console.log("Error when finding facebook user in verify callback"); done(err); } if(user) { console.log("User has been found in facebook verify callback"); done(null,user); } else { console.log("Creating new user in facebook verify callback"); var payload = { facebook:{ id:profile.id, token:profile.token, name: profile.name.givenName, email:profile.emails[0].value } }; console.log(payload); var user = new User(payload); user.save(function(err,user){ if(err){ console.log("Error occured when creating new user in facebook verify callback"); done(err); } else { console.log("New facebook user added successfully"); done(null,user); } }) } }); } process.nextTick(findOrCreateUser); }; 

我在app.js中调用这两个来configuration它们:

 //after setting up views,passport require('./auth/facebook')(passport); require('./auth/google')(passport); //setting up login route here app.use('/login',login); 

login路线如下所示:

  var router = require('express').Router(); var passport = require('passport'); router.get('/facebook',passport.authenticate('facebook',{scope:'email'}),function(req,res){ console.log('Login request sent for fb'); }); router.get('/facebook/callback', passport.authenticate('facebook',{failureRedirect:'/',successRedirect:'/home'}),function(req,res){ }); router.get('/google', passport.authenticate('google', {scope:['https://www.googleapis.com/auth/plus.login', 'https://www.googleapis.com/auth/plus.profile.emails.read' ]}) ,function(req,res){ }); router.get('/google/callback', passport.authenticate('google',{successRedirect:'/home',failureRedirect:'/'}), function(req,res){ console.log("Google auth callback"); }); router.get('basic',passport.authenticate('basic_login',{ successRedirect:'/home',failureRedirect:'/'}), function(req,res){ }); router.get('basic/newuser',passport.authenticate('basic_signup',{ successRedirect:'/home',failureRedirect:'/'}), function(req,res){ }); module.exports = router; 

当我用googlelogin时,我发现它使用google verifyCallback,但是它首先用facebook进行序列化和反序列化,然后用gooogle的serializeUser和deserializeUser方法:

 User exists in google verify callback { _id: 54c8958b9c04cd101c1b626e, __v: 0, twitter: {}, basic: {}, google: { token: 'ya29.CQFm2SD2KRjrweF2Jd30-IS5vL9q8aSct48PdhZiVlXAWwC-tIMg-zgqCcRfoO gZ0HyhvrOnCFiEcg', email: 'vamsideepak03@gmail.com', id: '118287466982176787421', name: 'vamsi deepak ampolu' }, facebook: {} } Serializing facebook user { _id: 54c8958b9c04cd101c1b626e, __v: 0, twitter: {}, basic: {}, google: { token: 'ya29.CQFm2SD2KRjrweF2Jd30-IS5vL9q8aSct48PdhZiVlXAWwC-tIMg-zgqCcRfoO gZ0HyhvrOnCFiEcg', email: 'vamsideepak03@gmail.com', id: '118287466982176787421', name: 'vamsi deepak ampolu' }, facebook: {} } Serializing google user { _id: 54c8958b9c04cd101c1b626e, __v: 0, twitter: {}, basic: {}, google: { token: 'ya29.CQFm2SD2KRjrweF2Jd30-IS5vL9q8aSct48PdhZiVlXAWwC-tIMg-zgqCcRfoO gZ0HyhvrOnCFiEcg', email: 'vamsideepak03@gmail.com', id: '118287466982176787421', name: 'vamsi deepak ampolu' }, facebook: {} } GET /login/google/callback?code=4/axqAPv7ohMJ-GXMZogBVKXLGgr9-NtrHmVJjehA6FSI.Yj sut3J2NE4Qcp7tdiljKKaHYQtglgI&authuser=0&num_sessions=1&session_state=d0ea095dd2 c27166100630f36550215211a2a35f..350c&prompt=none 302 1592.895 ms - 66 Deserializing facebook user null 

我发现序列化和反序列化只能在每个应用程序中定义一次,每个机制都应该使用它来维护用户。

这是我的序列化/反序列化代码:

  var facebook = require('./facebook'); var google = require('./google'); var basic = { login:require('./basic/login'), signup:require('./basic/signup') }; var twitter = require('./twitter'); var dropbox = require('./dropbox'); var User = require('../models/user'); module.exports = function(passport,config){ var serializeCallback = function serializeCallback(user,done){ console.log("Serializing user"); console.log(user); done(null, user.id); }; var deserializeCallback = function deserializeCallback(id,done){ console.log("Deserializing user"); console.log(id); var findUser = function findUser(err,user){ if(err) console.log("An error occured while deserializing user"); else console.log(user); done(err,user); } User.findById(id,findUser); }; passport.serializeUser(serializeCallback); passport.deserializeUser(deserializeCallback); /*Tested google and facebook successfully*/ if(config.basic) { basic.login(passport); basic.signup(passport); } if(config.facebook) facebook(passport); if(config.google) google(passport); if(config.twitter) twitter(passport); if(config.dropbox) dropbox(passport); } 

每个提供程序都设置在这样的文件夹(使用Facebook作为例子):

  facebook index.js verifyCallback.js //verifyCallback.js var User = require('../../models/user'); module.exports = function(accessToken, refreshToken, profile, done) { function findOrCreateUser(){ User.findOne({'facebook.id':profile.id},function(err,user){ if(err) { console.log("Error when finding facebook user in verify callback"); done(err); } if(user) { console.log("User has been found in facebook verify callback"); done(null,user); } else { console.log("Creating new user in facebook verify callback"); var payload = { facebook:{ id:profile.id, token:profile.token, name: profile.name.givenName, email:profile.emails[0].value } }; console.log(payload); var user = new User(payload); user.save(function(err,user){ if(err){ console.log("Error occured when creating new user in facebook verify callback"); done(err); } else { console.log("New facebook user added successfully"); done(null,user); } }) } }); } process.nextTick(findOrCreateUser); }; //index.js var config = require('../config'); var FacebookStrategy = require('passport-facebook').Strategy; var verifyCallback = require('./verifyCallback'); module.exports = function(passport){ var fbConf = { clientID: config.facebook.clientId, clientSecret: config.facebook.clientSecret, callbackURL: config.facebook.callbackURL, enableProof: false, }; passport.use(new FacebookStrategy(fbConf,verifyCallback)); };