Loopback passport-facebook для многопользовательских моделей - PullRequest
0 голосов
/ 23 января 2019

Я использую паспорт для аутентификации пользователей моего приложения с помощью Facebook.В моем приложении у меня есть 2 разных пользователя: клиенты и специалисты (переходя к «экспертам»).

Я следовал Loopback docs , чтобы реализовать пакет loopback-component-passport и passport-Facebook и он работает для моих клиентов .

Поскольку я использую пользовательские модели пользователей, я следовал этому SO Post о том, как это исправить (примечание: я все ещеиспользуйте встроенную модель AccessToken).

Angular Frontend

Я использую Angular Frontend.Чтобы перенаправить пользователя обратно на мой веб-интерфейс, я создал загрузочный скрипт, который выглядит следующим образом:

'use strict';

module.exports = function(app) {
  var router = app.loopback.Router();
  var cookieParser = require('cookie');

 // Redirect user to page set in env.APP_HOST
 router.get('/auth/customer/success', function(req, res, next) {
     const cookie = req.headers.cookie;
     var result = cookieParser.parse(cookie);
     res.redirect(process.env.APP_HOST + '/auth/facebook/?token=' + 
         result['access_token'] + '&id=' + result['userId'] + 
         '&err=&fbsr=');
 });

 router.get('/auth/expert/success', function(req, res, next) {
     const cookie = req.headers.cookie;
     var result = cookieParser.parse(cookie);
    res.redirect(process.env.APP_HOST + '/expert/auth/facebook/?token=' 
        + result['access_token'] + '&id=' + result['userId'] + 
        '&err=&fbsr=');
 });

 app.use(router);
};

Когда я аутентифицируюсь как клиент, я должен быть перенаправлен на https://example.com/auth/customer/success Когда я аутентифицируюсь какпрофессионал / эксперт, я должен быть перенаправлен на https://example.com/auth/expert/success.

Настройка второго паспорта-facebook

Я должен загрузить конфигурацию как для клиента, так и для профессионала / эксперта, который я делаю вserver.js.Я создал 2 файла provider.json ( provider.customer.json и provider.professional.json ), в которых содержится их конкретная информация.

Вот так я загружаю обе конфигурации(возможно, немного грязно):

var passportCustomer = require('loopback-component-passport');
var PassportConfiguratorCustomer = passportCustomer.PassportConfigurator;
var passportConfiguratorCustomer = new PassportConfiguratorCustomer(app);
var passportProfessional = require('loopback-component-passport');
var PassportConfiguratorProfessional = passportProfessional.PassportConfigurator;
var passportConfiguratorProfessional = new PassportConfiguratorProfessional(app);

// Setup passport configuration
var passportCustomerConfig = {};
var passportProfessionalConfig = {};
try {
    passportCustomerConfig = require('./providers.customer.json');
    passportProfessionalConfig = require('./providers.professional.json');
} catch(err) {
    console.log('Please configure the passport strategy in providers.customer.json');
    console.error(err);
    process.exit(1); // Fatal error
}

// Init passport for customer
passportConfiguratorCustomer.init(false);
passportConfiguratorProfessional.init(false);

// Setup passport models
passportConfiguratorCustomer.setupModels({
  userModel: app.models.Customer,
  userIdentityModel: app.models.UserIdentityCustomer,
  userCredentialModel: app.models.UserCredentialsCustomer
});

passportConfiguratorProfessional.setupModels({
  userModel: app.models.Professional,
  userIdentityModel: app.models.UserIdentityProfessional,
  userCredentialModel: app.models.UserCredentialsProfessional
});

// Configure passport for customer
for(var s in passportCustomerConfig) {
    var c = passportCustomerConfig[s];
    c.session = c.session !== false;
    passportConfiguratorCustomer.configureProvider(s, c);
}

// Configure passport for professional/expert
for(var s in passportProfessionalConfig) {
    var c = passportProfessionalConfig[s];
    c.session = c.session !== false;
    // passportConfiguratorProfessional.configureProvider(s, c);
    passportConfiguratorCustomer.configureProvider(s, c);
}

Актуальная проблема

У меня есть 2 разных приложения в Facebook (1 для клиентов, 1 для профессионалов / экспертов).Когда я аутентифицируюсь, используя localhost: 3000 / auth / customer / facebook или localhost: 3000 / auth / expert / facebook, я вижу, что оба приложения используются для правильной конечной точки.Но независимо от того, какую конечную точку я использую, после аутентификации меня всегда перенаправляют на http://example.com/expert/auth/facebook

Поэтому мой вопрос: Как я могу исправить эту проблему, чтобы клиенты перенаправлялись к клиентуконечная точка и эксперты / профессионалы перенаправлены на свою экспертную конечную точку?

Дополнительная информация

  • Регистрация работает нормально, я могу найти клиентов в таблице клиентов и эксперта в таблице экспертов в моей базе данных

Для справки: provider.customer.json

{
  "facebook-login": {
    "provider": "facebook",
    "module": "passport-facebook",
    "clientID": "OhOh, I removed it :)",
    "clientSecret": "Supa Dupa secret",
    "callbackURL": "/auth/customer/facebook/callback",
    "authPath": "/auth/customer/facebook",
    "callbackPath": "/auth/customer/facebook/callback",
    "successRedirect": "/auth/customer/success",
    "failureRedirect": "/auth/customer/failure",
    "scope": ["email"],
    "failureFlash": true,
    "profileFields" : ["locale", "name", "email"]
  },
  "facebook-link": {
    "provider": "facebook",
    "module": "passport-facebook",
    "clientID": "OhOh, I removed it :)",
    "clientSecret": "Supa Dupa secret",
    "callbackURL": "/link/customer/facebook/callback",
    "authPath": "/link/customer/facebook",
    "callbackPath": "/link/customer/facebook/callback",
    "successRedirect": "/auth/customer/success",
    "failureRedirect": "/auth/customer/failure",
    "scope": ["email"],
    "link": true,
    "failureFlash": true
  }
}

Для справки: provider.professional.json

{
  "facebook-login": {
    "provider": "facebook",
    "module": "passport-facebook",
    "clientID": "Aaaaand",
    "clientSecret": "It's gone",
    "callbackURL": "/auth/expert/facebook/callback",
    "authPath": "/auth/expert/facebook",
    "callbackPath": "/auth/expert/facebook/callback",
    "successRedirect": "/auth/expert/success",
    "failureRedirect": "/auth/expert/failure",
    "scope": ["email"],
    "failureFlash": true,
    "profileFields" : ["locale", "name", "email"]
  },
  "facebook-link": {
    "provider": "facebook",
    "module": "passport-facebook",
    "clientID": "Aaaaand",
    "clientSecret": "It's gone",
    "callbackURL": "/link/expert/facebook/callback",
    "authPath": "/link/expert/facebook",
    "callbackPath": "/link/expert/facebook/callback",
    "successRedirect": "/auth/expert/success",
    "failureRedirect": "/auth/expert/failure",
    "scope": ["email"],
    "link": true,
    "failureFlash": true
  }
}

1 Ответ

0 голосов
/ 17 июня 2019

Так что я смог исправить это с помощью метода PassPortConfigurator#configureProvider. Вместо того, чтобы использовать файлы JSON для настройки аутентификации Facebook, я сделал это в JS.

var passportCustomer = require('loopback-component-passport');
var PassportConfiguratorCustomer = passportCustomer.PassportConfigurator;
var passportConfiguratorCustomer = new PassportConfiguratorCustomer(app); // Note the first letter is not a capital one

// Init passport for customer
passportConfiguratorCustomer.init(false);

// Setup passport models
passportConfiguratorCustomer.setupModels({
  userModel: app.models.Customer,
  userIdentityModel: app.models.UserIdentityCustomer,
  userCredentialModel: app.models.UserCredentialsCustomer
});

// Load configuration here instead of the JSON file.
passportConfiguratorProfessional.configureProvider('facebook-login-expert', {
  module: 'passport-facebook',
  clientID: XXX,
  clientSecret: XXX,
  callbackURL: '/auth/expert/facebook/callback',
  authPath: '/auth/expert/facebook',
  callbackPath: '/auth/expert/facebook/callback',
  successRedirect: '/auth/expert/success',
  failureRedirect: '/auth/expert/failure',
  scope: ['email'],
  failureFlash: true,
  profileFields: ['locale', 'name', 'email']
});
...