Angular 对 JWT 使用 booth cookie 或拦截器有用吗?

Angular is it useful to use booth cookie or interceptor for JWT?

我有一个后端 api 只能通过身份验证访问。这是通过 JSON web Token (JWT) 提供的,一旦给出了一对正确的凭证。

现在我正在使用 Angular9 为我的应用程序开发前端。登录由 auth.service 管理,如果提供了正确的凭据,则 return 一个 JWT。

在对服务器的第一个请求(登录请求)之后,我设置了一个 interceptor 用于将后续请求中的 JWT 值插入到 api。现在,我的一位同事说我们必须将令牌值存储在浏览器的 cookie 中。

对我来说,我找不到任何理由这样做:如果我们已经有了拦截器来验证请求,为什么还要在浏览器中存储凭据?

所以有几种方法可以回答这个问题:

这一切都归结为安全问题。因此,如果您将 JWT 令牌(应该始终不是长期数据)存储在 LocalStorage/SessionStorage 或 Cookie 中。

不同之处在于,可以从域中的每个 javascript 文件访问 LocalStorage/SessionStorage,如果处理不当,可能会产生跨站点脚本 (XSS) 安全问题。为了防止自己受到 XSS 攻击,我建议对所有不受信任的数据进行转义和编码。

所以实际上所有从前端到后端的通信。在 SPA 世界中,永远不要从前端推送数据并始终在后端检查它是一种标准。

对于使用 HttpOnly 时的 Cookie,无法通过 JavaScript 访问这些 cookie。还要确保设置 Secure 标志,这样这个 cookie 只能通过 HTTPS 发送(不用动脑筋)。当然 Cookie 也有其安全问题,您需要防止自己受到跨站点请求伪造 (CSRF) 的侵害。 如果您想了解更多相关信息,请阅读有关在您的 JWT 声明中添加 XSRF-TOKEN 的内容。

简而言之,我还建议使用 cookie 而不是 LocalStorage/SessionStorage。

一些有趣的读物:

用于允许 Angular 应用程序执行仅允许经过身份验证的用户的 http 请求的 JWT 令牌。

因此,在用户通过身份验证后,您将需要 JWT。

然后,拦截器可用于在 HTTP 请求执行之前查看它是否具有 JWT,如果没有则将其添加到 HTTP 请求中。

现在,问题是:我将 JWT 存储在应用程序中的什么位置,以便在您需要向后端服务器发出 HTTP 请求时不向用户请求身份验证?

您有两个选择:Local/Session 存储(出于安全原因不推荐)和 Cookie。

大多数 Angular/Web 课程或博客都展示了使用 local/session 存储的示例,但由于安全问题,不推荐这样做。这是一个很好的解释: https://dev.to/rdegges/please-stop-using-local-storage-1i04

因此,存储 JWT 的最佳位置是 cookie。

编辑

我刚刚又看了一遍你的问题,你根本没有提到localStorage。所以如果你的 JWT 只存储在内存中,当你刷新页面时它会丢失,就像 MikeOne 在他的评论中所说

结束编辑

如果您已经在使用 localStorage,一个合理的理由是您打算使用 angular universal 来进行服务器端渲染。

如果您渲染图像服务器端,则本地存储不存在,因此您的 api 调用将不会包含 JWT 令牌。

这意味着服务器响应可能会将您重定向到登录页面,即使您已经登录,或者您可能会在连接的用户仅显示内容之前短暂看到页面的 public 版本客户端边

关于事物的安全方面,请查看 this SO answer