用于保护 API 的身份验证令牌的安全 HttpOnly Cookie 或标头字段?

信息安全 验证 令牌
2021-08-10 18:09:37

我有一个 API 来保护。这个 API 可能有两种类型的消费者——我们自己的单页应用程序,以及将与其集成的第三方服务。

我已经读过,通常 REST API 不支持 cookie,最好使用标头字段。也许这只是惯例。

安全 cookie 是在 SPA 中保存身份验证令牌的更好位置。它可以防止它们被跨站点脚本攻击获得。此外,如果 SPA 打开一个新窗口/选项卡,则 sessionStorage 不会流过,导致用户必须再次登录。您可以使用 localStorage,但将身份验证令牌保留在那里并不是一个好主意,因为它仍然存在。

我应该让服务器端的身份验证过滤器接受 cookie 还是标题字段?先试试 cookie,如果没有,再试试 header 字段?SPA 将使用 Cookie,其他 API 消费者将使用标头字段。或者,只使用一种传输身份验证令牌的方式会更好吗?

2个回答

如果使用得当,我认为 cookie 或标头之间的安全性不会有很大差异。

Cookie 旨在维护服务器状态。因此,如果您有一个启动会话的登录调用,那么 cookie 就有意义。如果您使用在 API 之外分发的 API 令牌,则 cookie 没有意义。

最后,cookie 也是在 headers 中发送的,因此它们的传输方式几乎没有区别。不同之处在于浏览器如何处理 cookie:

  • 可以将 cookie 设置为 HttpOnly,使 JavaScript 无法访问它们;
  • Cookie 包含在浏览器的每个请求中。

HttpOnly 提供一些针对 XSS 的保护。但是,攻击者可以在获得 XSS 时以任何他想要的方式调用您的 API,即使他没有获得 cookie。

每个请求中都包含 cookie,这使其容易受到跨站点请求伪造 (CSRF) 的攻击:另一个网页可以触发对您的 API 的请求,并且默认情况下包含 cookie。

在 SPA 中,存储令牌的替代方法是在 JavaScript 变量中。这仅在选项卡打开时保留,并且如果变量的范围有限,则可能对 XSS 是安全的。

将令牌存储在 localStorage 中会使它们永远保存在那里,因为当应用程序关闭时 localStorage 不会被清除。但是,这还不错,因为您可以使服务器上的令牌过期。即使令牌由于保存在 localStorage 中而在一段时间后暴露,令牌也将不再有效。

还可以使用两个令牌,一个在 cookie 中,一个在标头中。您需要两个令牌才能成功使用 API。由于 cookie 是 HttpOnly,因此您可以免受 XSS 攻击。由于不是在每个请求上都发送标头,因此您受到 CSRF 的保护。

对于您描述的情况,我建议仅在 cookie 中传输身份验证信息。正如您所提到的,这可以防止用户的身份验证令牌从您的单页应用程序中泄露。

作为额外的好处,将身份验证令牌作为 cookie 简化了身份验证过滤器中的逻辑,因为只有一个地方可以检查。

请注意,如果您的 SPA 中存在 XSS 缺陷,攻击者 JavaScript 仍然可以发出请求冒充用户,无论您使用 cookie 还是标头作为身份验证令牌。所以,请清理你的输出:-)