首页 > 解决方案 > 用于多个用户模型的环回护照-facebook

问题描述

我正在使用护照通过 Facebook 对我的应用程序的用户进行身份验证。在我的应用程序中,我有 2 个不同的用户:客户和专业人员(过渡到“专家”)。

我按照 Loopback文档实现了 loopback-component-passport 包和 passport-facebook 并让它为我的客户工作。

因为我使用自定义用户模型,所以我遵循了这篇关于如何修复该问题的SO Post (注意:我仍然使用内置的 AccessToken 模型)。

角前端

我使用 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 当我以专业/专家身份进行身份验证时,我应该重定向https://example.com/auth/expert /成功

设置第二个护照-facebook

我必须为我在 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 个用于专业人士/专家)。当我使用 localhost:3000/auth/customer/facebook 或 localhost:3000/auth/expert/facebook 进行身份验证时,我看到这两个应用程序都用于正确的端点。但无论我使用什么端点,身份验证后我总是被重定向到http://example.com/expert / auth /facebook

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

附加信息

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

标签: javascriptnode.jspassport.jsloopbackjspassport-facebook

解决方案


所以我能够通过使用该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']
});

推荐阅读