使用 Facebook 和 Google 使用 passport-google-oauth2 进行身份验证

Authenticating with Facebook and Google using passport-google-oauth2

我正在尝试分别使用 passport-google-oauth2passport-facebook 通过 facebook 和 google 进行身份验证。

我的 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); 
};

这是 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 中调用了这两个:

//after setting up views,passport
require('./auth/facebook')(passport);
require('./auth/google')(passport);
//setting up login route here
app.use('/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;

当我使用 google 登录时,我发现它使用 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

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

这是我的 serialization/deserialization 代码:

 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));
};