2015-08-20 25 views
4

我想以不同的方式处理以下与护照相关的操作。我可以拥有多种facebook护照策略吗?

  1. 登录了Facebook的
  2. 登录与Facebook
  3. 连接现有的帐户给Facebook

对于 '申请' 我想做/检查:

  • 如果用户已经存在(基于Facebook oauth id),重定向到登录。
  • 如果用户已经存在(基于Facebook个人资料中的电子邮件地址),请提示用户使用电子邮件登录,然后连接他们的Facebook帐户。
  • 创建一个新用户&在他们签名。

对于“登录”和“连接的帐户”我要执行一系列其他检查/操作。

我已经看过passport documentation for facebookpassport-facebook module和一堆相关的堆栈溢出问题,但我仍然在为如何实现这个问题而苦苦挣扎。

如何使用不同的callbackURL和选项实现不同的facebook策略(通过护照)?

回答

7

一个很好的协议的挖掘之后,这是我落得这样做:


创建3个独立的护照策略。

每个都有不同的名称(facebookSignUp vs facebookLogIn vs facebookConnect)和不同的callbackURL路径(... /注册/ clbk vs .../log-in/clbk vs .../connect/clbk)。

// facebook strategy 1 (sign-up with facebook) 
passport.use('facebookSignUp', new FacebookStrategy({ 
     clientID: FACEBOOOK_APP_ID, 
     clientSecret: FACEBOOK_APP_SECRET, 
     callbackURL: 'http://website/auth/facebook/sign-up/clbk' 
    }, 
    function(accessToken, refreshToken, profile, clbk) { 
     return clbk(profile); 
    } 
)); 

// facebook strategy 2 (log-in with facebook) 
... 

// facebook strategy 3 (connect facebook to existing account) 
... 

为每个策略创建路由。

初始请求路由& facebook认证后的回叫路由。所以每个策略2条路线。

var member = require('../member');    // member module controller 

// sign-up with facebook 
app.route('/auth/facebook/sign-up') 
    .get(member.facebookSignUp);    // passport redirect to facebook for authentication 

// sign-up with facebook callback 
app.route('/auth/facebook/sign-up/clbk') 
    .get(
    member.facebookSignUpClbk,     // parse facebook profile to create new user & check for existing account -> redirect to log-in route 
    member.checkEmail,       // check if email is already used -> throw error 'please log in with email, then connect facebook in settings' 
    member.checkUrl,       // get unique url 
    member.signUp,        // create new user & sign-in 
    member.email.welcome,      // send welcome email 
    member.facebookRedirectDashboard   // redirect to member dashboard 
); 

// log-in with facebook 
app.route('/auth/facebook/log-in') 
    .get(member.facebookLogIn);     // passport redirect to facebook for authentication 

// log-in with facebook callback 
app.route('/auth/facebook/log-in/clbk') 
    .get(
    member.facebookLogInClbk,     // authenticate user and log-in & check if user exists (fb oauth id or email address) -> throw error 'please sign up with facebook or log in with email' 
    member.lastLogin,       // update user's last login field 
    member.facebookRedirectDashboard   // redirect to dashboard 
); 

// connect facebook profile to existing account 
... 

// connect facebook profile to existing account clbk 
... 

其中在以下文件/函数中执行实际护照验证。

member.facebookSignUp只是调用passport.authenticate(),它重定向到Facebook。

// member.facebookSignUp 
exports.facebookSignUp = function(req, res, next) { 
    passport.authenticate('facebookSignUp', {   // use the 'facebookSignUp' strategy 
     display: null,         // null = let facebook decide (or 'page' (default), 'popup', 'touch', etc) 
     scope: [ 
      'public_profile',       // profile returned by default, but specified here anywhere 
      'email',         // ask for email address 
      'user_location'       // ask for location 
     ] 
    })(req, res); 
}; 

member.facebookSignUpClbk在facebook授权用户并重定向到回调路由后执行。这是一切发生的地方。

// member.facebookSignUpClbk 
exports.facebookSignUpClbk = function(req, res, next) { 

    // parse profile & plug into req.body for new user creation in later fxn 
    function parseProfile(profile) { 
     // user doc 
     req.body = {}; 
     // facebook profile data 
     req.body.facebook = (profile._json) ? profile._json : {id: profile.id}; 
     // name 
     ... 
     // email 
     ... 
     next(); 
    } 

    // check existing users (mongoose/mongodb) 
    function checkUser(profile) { 
     User.findOne({query}, function(err, userDoc) { 
      if (err) { 
       return res.redirect(
        'http://'+req.headers.host+ 
        '?header=Sign-Up Error!'+ 
        '&message=We had trouble signing you up with Facebook. Please try again' 
       ); 
      } else if (userDoc) { 
       // redirect to log-in fxn 
       return res.redirect('http://website/auth/facebook/log-in'); 
      } else { 
       parseProfile(profile); 
      } 
     }); 
    } 

    // passport authentication 
    function passportAuth() { 
     passport.authenticate('facebookSignUp', function(profile) { 
      if (!profile || !profile.id) { 
       return res.redirect(
        'http://'+req.headers.host+ 
        '?header=Sign-Up Error!'+ 
        '&message=We had trouble signing you up with Facebook. Please try again or sign-up via email.' 
       ); 
      } else { 
       checkUser(profile); 
      } 
     })(req, res); 
    } 

    // start process 
    passportAuth(); 
}; 

member.facebookLogIn,.facebookLogInClbk,.facebookConnect,&。facebookConnectClbk是以类似的方式设置的,只是在'Clbk'函数中的不同逻辑取决于我正在尝试做什么。


希望这有助于!

+0

感谢您的努力 –

+0

资本发现!我遇到类似的问题。这太棒了。 –

相关问题