4

Я хочу обрабатывать следующие операции, связанные с паспорт-facebook, по-разному.Могу ли я иметь несколько стратегий facebook для паспорта?

  1. Sign-Up с Facebook
  2. Log-In с Facebook
  3. Connect существующую учетную запись в Facebook

Для 'Зарегистрировать' Я хочу сделать/проверить:

  • Если пользователь уже существует (на основе facebook oauth id), перенаправляйтесь на вход в систему.
  • Если пользователь уже существует (на основе адреса электронной почты из профиля facebook), попросите пользователя войти в систему по электронной почте, а затем подключить свою учетную запись facebook.
  • Создание нового пользователя & подписать их.

Для «вход в систему» ​​и «подключить учетную запись:» Я хочу, чтобы выполнить ряд других проверок/операций.

Я просмотрел passport documentation for facebook и passport-facebook module и кучу связанных вопросов переполнения стека, но я все еще борюсь с тем, как это реализовать.

Как я могу реализовать различные стратегии facebook (через паспорт) с различными callbackURL и параметрами?

ответ

7

После изрядной копания, это то, что я в конечном итоге делает:


Создание 3 отдельных стратегий паспорта.

Каждый с разными именами (facebookSignUp против facebookLogIn против facebookConnect) и различными путями CallBackURL (.../Регистраций/clbk против .../вход в систему/clbk против .../подключения/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) 
... 

Создать маршруты для каждой стратегии.

Первоначальный запрос route & callback route после аутентификации 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 просто вызывает паспорт.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

Столичная находка! Я столкнулся с подобными проблемами. Это замечательно. –

Смежные вопросы