httpOnly cookie 中的 JWT - AuthGuard 和受保护的路由(Node.js、Angular)

Posted

技术标签:

【中文标题】httpOnly cookie 中的 JWT - AuthGuard 和受保护的路由(Node.js、Angular)【英文标题】:JWT in httpOnly cookie - AuthGuard and protected routes (Node.js, Angular) 【发布时间】:2020-03-25 21:34:43 【问题描述】:

我正在开发我的应用程序,我正在使用 JWT 进行身份验证和授权,我正在尝试找到存储 JWT 的最佳解决方案。 (在当前版本中,我将 JWT 存储在会话对象中的服务器上)

我目前的解决方案有很多问题,所以我决定采用不同的实现方式——将 JWT 存储在客户端的 httpOnly cookie 中。

我的问题是,我如何知道用户是否登录?(我需要知道这一点,因为 AuthGuard - 用于保护路由,例如 /home 应该已注销的用户无法访问)。由于 cookie 是 httpOnly,我无法在客户端验证它。

在当前的实现中,我在后端有特殊的路由,只是为了检查用户是否在会话对象中有 jwt。但这不是很好的实现——客户端每次想要加载受保护的路由时都必须发送请求。

感谢您的想法。

【问题讨论】:

但是如果你把它存储在本地存储中,比如说,你仍然可以通过 javascript 访问它。 (您可以将变量设置到本地存储中)。而且,我可能需要验证用户是否在发送请求之前登录。 对不起,误删了cmets,反正后端就是master。如果您将用户引导到主页,则必须触发 API(在休息客户端上),API 响应将负责重置值并提供新数据。存储在浏览器上只会让导航更快。 顺便说一句,我一直认为 JWT 应该代替服务器端会话存储。当用户登录时,服务器对其进行身份验证,将用户的标识符和可选的权限放入签名的 JWT 中,并将其返回给客户端。然后不需要将令牌保留在会话中 - 客户端持有令牌,将其传递给服务器,服务器验证签名,并从令牌本身确认用户和权限(如果存在)。这使得服务器更具可扩展性 - 不需要会话亲和或共享会话。 但是如何在客户端存储令牌?本地存储还是 cookie?两者都有一些缺点.. 【参考方案1】:

您可以设置 JWT 本身的到期日期。在客户端,您可以创建一个不断检查到期的循环(即:setInterval)。

我会仅依赖于存在 JWT 令牌这一事实表明“会话”有效。仅使用 JWT 令牌来识别用户是谁,例如使用 UUID、随机字符串等。

对于 API 的每个后续请求,在传递 JWT 令牌时,您应该始终在服务器端执行验证以确保:

    令牌信封有效(由您的密钥签名)。 唯一标识符对应一个有效的帐户/用户。

不要使用httpOnly cookie,几乎可以用于任何事情! 如果此 JWT 令牌被泄露(即:被无数设备捕获,您的 http 唯一流量将通过),它会暴露一个攻击向量,允许参与者模拟此用户会话。

要回答您的其他问题,您可以将 JWT 令牌存储在像 localStorage 这样的介质中。 JWT 的重量足够轻,预计您将它与每个请求一起发送。

希望这有助于为您阐明一些事情。如果您还有任何疑虑或问题,请告诉我!

【讨论】:

感谢您的回答!所以.. 基本上我唯一要做的就是在 LS 中存储令牌(我仍然担心它,比如 XSS 攻击..),然后使用令牌拦截器将 JWT 附加到请求标头中。然后,在我解码令牌的服务器上,检查令牌内的随机字符串是否等于与当前用户关联的数据库中的令牌。如果是这样,我会将数据发送给用户。但是如果 JWT 过期了怎么办?我应该制作诸如刷新令牌之类的东西吗? (JWT 过期后,客户端会自动向 /token 端点发送请求以获取新的 JWT)。感谢您的建议。 如果过期,您应该让用户重新登录;)

以上是关于httpOnly cookie 中的 JWT - AuthGuard 和受保护的路由(Node.js、Angular)的主要内容,如果未能解决你的问题,请参考以下文章

在 .net core api 中存储/验证存储在 HttpOnly cookie 中的 JWT 令牌

如何在前端使用 HttpOnly jwt cookie

用于传递 JWT 的 httpOnly Cookies 与授权标头

将 JWT 令牌存储到 HttpOnly cookie 中

如何在 ngCookies 中设置 httpOnly 标志?

在 Django/DRF 中使用 JWT 身份验证并将 JWT 存储在 HttpOnly Cookie 中