应该将访问令牌和刷新令牌都存储在本地存储中吗?

huangapple go评论65阅读模式
英文:

(JWT) Should I store both access token and refresh token in localStorage?

问题

我在存储HttpOnly cookies中遇到了问题,因为后端和前端必须在相同的域上才能使用cookies,而我对NGINX的反向代理设置不够熟悉。

因此,我已经准备了以下身份验证流程:

应该将访问令牌和刷新令牌都存储在本地存储中吗?

我打算同时将访问令牌和刷新令牌存储在localStorage中,也存储在数据库中以便在需要时使其无效。

每当访问令牌过期时,客户端会将刷新令牌发送到/refresh以获取新的令牌对,然后数据库中的旧令牌对将被新令牌对替换。

如果客户端的令牌与数据库中找到的令牌不匹配,则视为无效。

问题

如果在用户不活跃的时候发生XSS攻击,黑客可以无限期地使用刷新令牌,直到用户再次活跃。

我想知道如果不使用cookies,JWT的正确方法是什么。我非常愿意听取您的任何见解。

英文:

I'm having trouble with storing refresh token in HttpOnly cookies, simply because the backend and the frontend must be on the same domain for cookies to work, and I'm not good enough with NGINX to setup the reverse proxy.

For that reason, I have prepared the auth flow as follows:

应该将访问令牌和刷新令牌都存储在本地存储中吗?

I intend to store both access token and refresh token in localStorage and also in database for invalidating them if needed.

Everytime the access token expires, the client send the refresh token to /refresh for new pair of tokens, the old pair of tokens would then be replaced by the new pair in the database.

The tokens from the client are invalid if they do not match those found in the database.

The problem

If an XSS attack were to occur during the night when the user is not active, the hacker could use the refresh token indefinitely until the user becomes active again.

I want to know what is the correct approach to JWT if no cookies are used. I'm all ears for any insight you have.

答案1

得分: 1

我认为你的流程看起来正确。(但通常不需要将访问令牌存储在后端数据库中。我想你通常不会这样做。)

出于你担心的原因,你需要一个安全的存储方式,而这种攻击方式基本上是无法避免的。安全存储可以是cookie存储或会话存储。如果无法使用cookie,可以使用会话存储。

如果刷新令牌被窃取,那么在那个晚上你几乎无能为力。一旦用户再次尝试访问你的服务,你可以检测到旧的刷新令牌的使用,并作为一种安全措施登出用户。如果要求用户在更改密码时输入旧密码,你就可以防止黑客更改账户的密码。一旦真正的用户更改密码,你可以进行注销,从后端数据库中删除当前的刷新令牌,用户再次掌控账户。(但如果首次使用的漏洞仍然存在,那么很可能会再次被劫持。)

(例如,Auth0使用会话存储,详见此博客文章,了解更多关于他们特定设置的信息,看起来与你的设置有些相似。)

然后,你当然需要在其之上使用适当的CORS策略来保护自己。

英文:

I think your flow looks correct. (But there is probably no need to store the access token in the backend DB. You normally don't do that I would say.)

You need a safe storage for exactly that reason you are fearing, and that attack vector not really avoidable in any other way. Safe storage is either cookie storage or Session Storage. If you cannot use cookies, use session storage.

If the refresh token is stolen, there is not much you can do about it during that night. Once the user again tries to access your service, you can detect usage of an old refresh token and log out the user as a safety measure. If you require the user to enter the old password upon pw changes, you have prevented the hacker from changing pw of the account. Once the real user changes pw, you do a logout that removes the current refresh token from the backend DB, and the user is again in control of the account. (But if the vulnerability first used is still there, you are shot to get hijacked again.)

(The session storage is used by for example Auth0, see this blog post for more info on their specific setup that looks kind of close to yours.)

Then you need to protect yourself using proper CORS policy on top of that of course.

huangapple
  • 本文由 发表于 2023年7月23日 22:56:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76748899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定