【问题标题】:Single Page Web Apps, CORS and security concerns单页 Web 应用程序、CORS 和安全问题
【发布时间】:2017-01-04 23:41:50
【问题描述】:

情况

  1. 我正在编写一个单页 Web 应用程序(使用 Angular)。让我们称之为SPA
  2. 另一个队友正在编写一些 API(使用 Node.js)。让我们调用服务器
  3. 我的 SPA 是使用 login/passwd 登录到服务器,然后做一些事情

我的队友决定使用 cookie 来跟踪会话。因此,在成功登录后,将在加载 SPA 的网络浏览器中设置一个仅限 http 的 cookie。

问题

如果我们将 SPA 放在服务器的 public_html 目录中,一切正常。然而,这使得 SPA 成为 API 代码的一部分。这打破了我们的构建过程,因为每个版本升级到 SPA 现在也需要升级 API。

如果我们将 SPA 托管在仅提供静态 SPA 文件的单独网络服务器中,我会遇到 CORS 问题。由于 SPA 的来源与其尝试访问的 API 不同,因此浏览器会阻止 ajax 调用。为了克服这个问题,我们必须在服务器端适当地设置Access-Control-Allow-Origin。我也明白需要设置Access-Control-Allow-Credentials:true,以指示浏览器设置/发送cookies。

可能的解决方案

  1. 我们创建一个构建过程,每次升级 SPA 时都会对服务器的 public_html 目录执行 git-pull。我试图避免这种情况,以保持客户端和服务器升级分开。

  2. 我们创建了一种 代理 类型的情况,其中服务器不存储 SPA 文件,而是从托管 SPA 文件的另一台服务器按需收集它们。在这种情况下,网络浏览器将看到来自同一来源的 SPA 文件和后续 ajax 调用。

  3. 我们对服务器进行编码以在其响应中设置Access-Control-Allow-Origin:*。首先,这太开放了,看起来不安全。 它真的不安全,还是只是我的看法?另外,由于我们设置了Access-Control-Allow-Credentials:true,Chrome 会抱怨Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.。为了克服这个问题,我们必须在Access-Control-Allow-Origin 中输入确切的来源(可能使用正则表达式)。这可能会严重限制我们将 SPA 分发给未知域中的用户。

  4. 对于服务器 API 设计者,基于 Cookie 的身份验证是推荐处理 SPA 身份验证的方法吗? OAuth2.0 and JWT based Authentication 似乎暗示基于 Cookie 的身份验证不适合 SPA。有什么优点/缺点?

请对上述选项发表评论,或建议您可能使用过的任何其他选项。提前致谢。

【问题讨论】:

    标签: security cookies oauth cross-domain single-page-application


    【解决方案1】:

    我会选择解决方案 2 或 3。

    2:您可以在同一台服务器上同时设置(网页和 API)(或使用反向代理),这样从外部角度来看,它们共享相同的来源。

    3:在 API 的情况下,同源策略变得不那么重要了。该 API 将由不属于您的 Web 应用程序的客户端使用,不是吗? 在设置更宽松的允许来源标头时,我不会看到任何问题。更宽松的意思不是通配符,只需添加网页的来源即可。为什么要使用通配符?

    【讨论】:

      【解决方案2】:

      我认为问题在于您的术语令人困惑。 API 不是server,它是一个存在于也可以是server 的机器上的应用程序。如果你制作 NodeJS API,我建议你在它之前使用 Nginx 服务器作为反向代理。假设您希望 Nginx 服务器、API 和 SPA 文件都在同一台机器上,您可以将 API 部署到一个目录,将 SPA 部署到另一个目录,并让 Nginx 相应地路由请求。

      所以我相信解决方案 2 是可行的。从那里您可以通过增加实例数量(如果您使用 AWS)轻松扩展并对它们进行负载平衡或将您的 API 分离到其自己的应用程序服务器中。

      就身份验证而言。对于 SPA 或 API 请求,我一直更喜欢使用带有访问令牌的标头授权而不是 cookie。尽管您可以通过本地存储保存访问令牌,但每个请求都是自包含的并且不需要在浏览器上保存持久字符串的想法对我更有吸引力。

      【讨论】:

      • 谢谢丹。因此,您偏爱的解决方案 2 可能没有 SPA 和 Node.js 应用程序都位于同一台机器上的限制。只要拥有 SPA 的机器可以从拥有 Node.js 应用程序(或服务器,在我的客户端-服务器术语中)的机器访问,它就会工作。对吗?
      • 它真的只要您的端点终止到可以访问您的节点 API 和 SPA 文件的机器/服务器。如果有的话,我建议将您的 SPA 文件放在 Nginx 服务器上,并让您的 URL 指向它。然后从这里,让 Nginx 将请求定向到单独的应用程序服务器上的 Node API。
      • 再次感谢。让我们等待更多的cmets。您可以向我指出任何使用访问令牌进行标头授权的文献吗?和self-issued.info/docs/draft-ietf-oauth-v2-bearer.html一样吗?
      • 如果你愿意,你可以使用 OAuth,好处是可能已经有你可以使用的库了。但是,如果您的 API 很简单,并且您不需要使用类似于权限的 token_type,您可以使用哈希值制作自己的令牌,并将记录保存在映射到用户记录的数据库中
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 2016-03-29
      • 2018-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      相关资源
      最近更新 更多