最近我需要构建一个简单的 REST API,我阅读了关于最佳实践的不同文章,以尽可能减少我的网络应用程序的漏洞。在网上搜索,我找到了关于如何实现 JWT 令牌的不同教程,每个教程在某些方面都不同,我找不到一种节流良好的“通用方法”。最后,我找到了我认为最合理的解决方案,但我想确认这是处理此类身份验证的最有效方法。
开始之前:
#STEP 1:身份验证后生成令牌:
#STEP 2:授权请求
要授权请求,我仅使用在请求标头中的字段中发送的访问令牌。仅当令牌有效时才允许请求。
#STEP 3:刷新访问令牌
为了刷新令牌,我向服务器发送刷新请求。服务器:
有关刷新过程的更多信息
刷新被调用:
进一步的预防措施:关键操作
刷新令牌有两个过期时间。第一个,对于非关键操作,每次发布新令牌时都会刷新。这样,如果用户继续使用该应用程序,他/她可能会永远保持登录状态。对于关键操作,第二个(持续 3 小时)是“绝对的”。这意味着,在每次刷新时,关键操作的“计时器”不会刷新。
//To make it simpler:
nextToken.criticalExpiration=previousToken.criticalExpiration
在“关键”计时器到期后调用刷新请求时,生成的访问令牌有一个字段为 false,表示执行关键操作的选项。如果为 false,则不允许进行关键操作(因此用户必须重新进行身份验证才能执行这些请求)
总结:
我想了解此过程是否正确执行或是否会产生漏洞。我知道应用的其他部分和/或外部库中始终可能存在漏洞,但是,我希望尽量减少留下可被利用的内容的可能性。
答案 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
<块引用>刷新被调用:
我同意,或者您可以使用 axios 拦截器,当响应 401(未授权)时您可以发送刷新令牌。
我同意
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/ 了解更多详情。