用于多用户模型的环回护照-facebook

Loopback passport-facebook for multiple user models

我使用护照为我的 Facebook 应用程序的用户进行身份验证。 在我的应用程序中,我有 2 个不同的用户:客户和专业人士(过渡到 "experts")。

我按照 Loopback docs 实现了 loopback-component-passport 包和 passport-facebook 并让它为我的 客户.

工作

因为我使用自定义用户模型,所以我遵循了这个 如何解决这个问题(注意:我仍然使用内置的 AccessToken 模型)。

Angular 前端

我使用 Angular 前端。为了将用户重定向回我的前端,我创建了一个如下所示的引导脚本:

'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 当我验证为 professional/expert 时,我应该被重定向到 https://example.com/auth/expert/success.

设置第二个护照-facebook

我必须为客户和 professional/expert 加载我在 server.js 中所做的配置。我创建了 2 个 providers.json 文件(providers.customer.jsonprovider.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);
}

实际问题

我在 Facebook 中有 2 个不同的应用程序(1 个用于客户,1 个用于 professionals/experts)。当我使用 localhost:3000/auth/customer/facebook 或 localhost:3000/auth/expert/facebook 进行身份验证时,我发现这两个应用程序都用于正确的端点。但无论我使用什么端点,在身份验证后我总是被重定向到 http://example.com/expert/auth/facebook

所以我的问题是:我如何解决这个问题,以便将客户重定向到客户端点并 experts/professionals 重定向到他们的专家端点?

附加信息

供参考:providers.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
  }
}

供参考:providers.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
  }
}

所以我可以使用 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']
});