构建安全 JWT 身份验证流程的指南?

时间:2021-01-28 22:18:17

标签: reactjs security redux jwt

最近我需要构建一个简单的 REST API,我阅读了关于最佳实践的不同文章,以尽可能减少我的网络应用程序的漏洞。在网上搜索,我找到了关于如何实现 JWT 令牌的不同教程,每个教程在某些方面都不同,我找不到一种节流良好的“通用方法”。最后,我找到了我认为最合理的解决方案,但我想确认这是处理此类身份验证的最有效方法。

开始之前:

  • 注意实施 CORS 政策
  • 为了签署令牌,我使用了“标准”库
  • 客户端和服务器之间的通信是加密的 (HTTPS)

#STEP 1:身份验证后生成令牌:

  1. 我生成了一个短期访问令牌(15 分钟)和一个使用 HS256 算法(使用的密钥长度:512 位)签名的“长期”刷新令牌(7 天)
  2. 此外,我将刷新令牌的 ID 存储在缓存中。
  3. 我在响应中将访问令牌发回(在客户端,我只将它保存在内存 [Redux] 中),同时我在 HTTPOnly cookie 中设置刷新令牌以使 XSS 攻击更加困难(并非不可能,我知道:目标是避免/减少窃取 cookie 的可能性)

#STEP 2:授权请求

要授权请求,我仅使用在请求标头中的字段中发送的访问令牌。仅当令牌有效时才允许请求。

#STEP 3:刷新访问令牌

为了刷新令牌,我向服务器发送刷新请求。服务器:

  1. 检查刷新令牌签名是否有效
  2. 检查刷新令牌是否在缓存中(检查是否过期并针对伪造令牌设置另一层防御)
  3. 同时生成新的访问令牌和新的刷新令牌,同时撤销先前的刷新令牌(并相应地更新缓存)
  4. 返回响应中的访问令牌和仅 HTTP cookie 中的刷新令牌

有关刷新过程的更多信息

刷新被调用:

  1. 在访问令牌到期之前
  2. 在用户打开/刷新网络应用的确切时刻。这样,如果刷新令牌仍然有效,用户就会自动通过身份验证并准备好使用应用程序。 请注意,刷新令牌可以仅用于刷新访问令牌,而不能执行其他请求(为了避免 CSRF 攻击,cookie 不能用于对请求进行身份验证,但用户需要加载网站获取访问令牌)

进一步的预防措施:关键操作

刷新令牌有两个过期时间。第一个,对于非关键操作,每次发布新令牌时都会刷新。这样,如果用户继续使用该应用程序,他/她可能会永远保持登录状态。对于关键操作,第二个(持续 3 小时)是“绝对的”。这意味着,在每次刷新时,关键操作的“计时器”不会刷新。

//To make it simpler:
nextToken.criticalExpiration=previousToken.criticalExpiration

在“关键”计时器到期后调用刷新请求时,生成的访问令牌有一个字段为 false,表示执行关键操作的选项。如果为 false,则不允许进行关键操作(因此用户必须重新进行身份验证才能执行这些请求)

总结:

我想了解此过程是否正确执行或是否会产生漏洞。我知道应用的其他部分和/或外部库中始终可能存在漏洞,但是,我希望尽量减少留下可被利用的内容的可能性。

2 个答案:

答案 0 :(得分:1)

我不明白为什么刷新令牌有 2 个过期时间。 我认为一个就够了,只要确保使用刷新令牌轮换即可。

用户登录并获取访问令牌 (AT1) 和刷新令牌 (RT1)。 如果 AT1 过期并且用户使用 RT1,则需要使刷新令牌无效,然后将新的刷新令牌提供给用户,例如 RT2。

我将 RT1 保存在 redis 中(无效刷新令牌列表)

如果有人盗取RT1并使用它,服务器可以检查并知道RT1已经在redis中。

因此您需要使 RT2 以及属于 RT 1 和 RT2 的所有访问令牌无效。

这样做,用户需要重新登录。

见:https://auth0.com/docs/tokens/refresh-tokens/refresh-token-rotation

<块引用>

刷新被调用:

  1. 在访问令牌到期之前

我同意,或者您可以使用 axios 拦截器,当响应 401(未授权)时您可以发送刷新令牌。

我同意

  • 将访问令牌存储在内存(redux、vuex)或网络工作者中
  • 将刷新令牌存储在 httpOnly cookie 中以防止 JavaScript 读取它。
  • 使用安全 cookie,https
<块引用>

Auth0 建议将令牌存储在浏览器内存中作为最安全的选项。使用 Web Workers 处理令牌的传输和存储是保护令牌的最佳方式,因为 Web Workers 与应用程序的其余部分在单独的全局范围内运行。使用 Auth0 SPA SDK,其默认存储选项是利用 Web Workers 的内存存储。

从这里:https://auth0.com/docs/security/data-security/token-storage#browser-in-memory-scenarios

请注意,存储在内存中的任何值仍然容易受到 XSS 攻击,只是有人更难获得令牌。
https://community.auth0.com/t/why-is-storing-tokens-in-memory-recommended/17742/4

另一个好读物:https://indepth.dev/posts/1382/localstorage-vs-cookies

答案 1 :(得分:0)

您必须创建控制器、登录中间件、生成 jwt 令牌以及刷新令牌。 请参阅:https://stackabuse.com/authentication-and-authorization-with-jwts-in-express-js/ 了解更多详情。