【问题标题】:Authentication with separated client and server使用分离的客户端和服务器进行身份验证
【发布时间】:2017-07-08 15:01:55
【问题描述】:

我已经为客户端创建了 Angular 2 的 Web 应用程序,并为服务器端创建了带有 express 框架的 NodeJS

对于客户端,我使用angular-cli 生成了在lite-server 上运行的项目,因此我的客户端和服务器运行在两个不同的服务上。

我想集成ADFS 身份验证。 为了实现身份验证,我使用了passport-saml 包。 我的服务器端 API 中有一个中间件,需要用户进行身份验证。

直接到达服务器(没有客户端)时,身份验证过程可以正常工作。

但是,我无法通过@angular/http 访问API。 我尝试了来自服务器的简单GET 请求(中间件位于端点),结果我得到了没有重定向的身份验证页面(我认为这不是核心问题,但实际实现是) .

在对服务器和客户端使用单独的服务时,我应该如何正确实现身份验证?

【问题讨论】:

  • @Ron537_ 你有什么有用的解决方案吗?

标签: node.js angular authentication client-server passport.js


【解决方案1】:

您好,我也面临同样的问题,我的 Angular 项目托管在 4200 端口上。我的节点在 3000 端口上。 当我们有 2 个端口运行时,很难实现护照。

第 1 步 通过对公用文件夹进行 ng 构建来使 Angular 项目静态化。 确保angular-cli.json*"outDir": "../public",*

第 2 步 现在我们可以使用相同的节点端口访问角根请在您的节点 app.js 中添加以下代码

var path = require('path');
  // Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
app.get('*', function(req, res) {
     res.sendFile(path.join(__dirname, 'public/index.html'));
});

这将使您的 Angular 项目可以通过节点端口访问。

第 3 步: 现在我们可以在 UI 中添加护照登录按钮 并给出网址<a href="/passport/auth/twitter">twitter</a>

这不是解释性的意思是想问我一些疑问。

【讨论】:

  • 您的解决方案可以工作,但我的目标是将客户端与服务器分开,而不是将它们组合在同一个端口上。我所做的是我使用iframe将客户端直接连接到服务器的认证页面即/auth/login,然后在服务器成功认证用户后,我使用EJS引擎在页面中渲染用户数据并将其传递给带有 parent.postMessage 的客户端(在 iframe 之外)。这样,我可以将客户端和服务器保持在不同的端口上,并使用 passport.js 存档身份验证。
  • 我也在寻找单独的客户端和服务器。在同一个端口上结合客户端和服务器对我来说也不是一个解决方案。
【解决方案2】:

当客户端向服务器执行 GET 时,您没有详细说明失败的响应是什么。是400吗? 401? 404? 500?你收到 CORS 错误了吗?

您为什么使用 GET 作为您的登录端点。您应该直接在 POST 有效负载中发布凭据吗?

无论如何,在您的 angular2 代码中,您应该有一个带有登录方法的身份验证服务。登录方法应该像 ..

login(credentials) {
    return http.post(your_server_url, payload);
}

然后您可以订阅登录方法返回的 Observable,如果一切正常router.navigate 到主页,或者如果运行不顺利,则显示登录错误消息。

【讨论】:

    【解决方案3】:

    在 ..src/environments/environment.ts 中为 ui 和 server 设置单独的 url

     export const environment = {
      production: false,
      BASE_URL: 'http://localhost:4200',
      API_BASE_URL: 'http://localhost:5000',
    };
    

    在节点 app.js 中

        app.use('/', express.static('public'));
      app.get('*', function (req, res) {
        res.sendFile(path.join(process.cwd(), 'public', 'index.html'));
      });
    

    【讨论】:

    • passport.js 会将其视为同一个域吗?那么session呢。
    • 我不确定。我在我的应用程序中使用了它,Angular2 和 Node.js 运行良好。
    • 您是否在Expressapp.js 文件中编写了任何允许跨域请求 (CORS) 的代码?
    • app.use(function (req, res, next) { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE'); res.setHeader('Access-Control-Max-Age', 60 * 60 * 24 * 7); next(); });
    • 我不认为它会解决真正的问题。问题是Express-session 在同一个域(客户端 3000 和服务器也是 3000)中运行良好,但在不同的域(客户端 4200 和服务器 3000)中运行不佳。它会在每个新请求上生成一个新的session,并且不会为用户身份验证保留相同的会话。
    【解决方案4】:

    在您的开发环境中,您应该通过指示 Angular CLI 将所有请求代理到运行在单独端口上的后端服务器来完成此操作,只要您运行“ng serve”。 Angular 在https://angular.io/guide/build#proxying-to-a-backend-server 上有很好的文档说明如何做到这一点。这将使您的开发过程更快,因为您无需手动构建 Angular 应用程序来测试每个代码更改。

    运行生产构建时,Angular 会将分发的文件移动到 Angular.json 的“outputPath”属性中指定的位置(默认设置为“dist/”)。正如@Lijo 在他们的回答中提到的那样,您的主要生产服务器将从那里适当地为他们提供服务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 2017-10-07
      • 1970-01-01
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      相关资源
      最近更新 更多