在哪里存储客户端上的刷新令牌? [英] Where to store the refresh token on the Client?

查看:17
本文介绍了在哪里存储客户端上的刷新令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 SPA 应用程序使用以下架构(

这假设我的客户端应用程序知道刷新令牌,因为如果不存在用户凭据(例如电子邮件/密码),我需要它来请求新的访问令牌.

我的问题:我的客户端应用程序在哪里存储刷新令牌?关于这个主题有很多问题/答案,但关于刷新令牌的答案并不明确.

访问令牌和刷新令牌不应存储在本地/会话存储中,因为它们不是任何敏感数据的地方.因此,我会将 访问令牌 存储在 httpOnly cookie 中(即使有 CSRF),无论如何我对资源服务器的大多数请求都需要它.

但是刷新令牌呢?我不能将它存储在 cookie 中,因为 (1) 它也会随着每个请求发送到我的资源服务器,这也使它容易受到 CSRF 的攻击,并且(2) 它会发送具有相同攻击向量的访问/刷新令牌.

我能想到的三种解决方案:

<小时>

1) 将刷新令牌存储在内存中的 JavaScript 变量中,这有两个缺点:

  • a) 它容易受到 XSS 攻击(但可能不如本地/会话存储那么明显
  • b) 如果用户关闭浏览器标签,它会丢失会话"

尤其是后一个缺点会导致糟糕的用户体验.

<小时>

2) 将访问令牌存储在会话存储中,并通过 Bearer access_token 授权标头将其发送到我的资源服务器.然后我可以使用 httpOnly cookie 作为刷新令牌.这有一个我能想到的缺点:

  • a) 每次向资源服务器发出请求时,刷新令牌都会暴露给 CSRF.
<小时>

3) 将两个令牌保留在 httpOnly cookie 中,这具有上述缺点,即两个令牌都暴露于相同的攻击向量.

<小时>

也许除了我提到的缺点之外还有其他方式或更多方式(请告诉我),但最终一切都归结为我应该将刷新令牌保存在客户端的什么位置?它是 httpOnly cookie 还是内存中的 JS 变量?如果是前者,那么我应该把我的访问令牌放在哪里?

如果能从熟悉该主题的人那里获得有关如何以最佳方式执行此操作的任何线索,我们将非常高兴.

解决方案

您可以将加密的令牌安全地存储在 HttpOnly cookie 中.

https://medium.com/@sadnub/simple-and-secure-api-authentication-for-spas-e46bcea592ad

如果您担心长寿命的刷新令牌.您可以跳过存储它而根本不使用它.只需将访问令牌保留在内存中,并在访问令牌过期时进行静默登录.

<块引用>

不要使用 Implicit 流,因为它是 过时.

SPA 最安全的身份验证方式是 授权码PKCE.

一般来说,最好使用基于 oidc-client 的现有库而不是自己构建一些东西.

My SPA application uses the following architecture (source):

This assumes that my client application knows about the refresh token, because I need it to request a new access token if no user credentials (e.g. email/password) are present.

My question: Where do I store the refresh token in my client-side application? There are lots of questions/answers about this topic on SO, but regarding the refresh token the answer are not clear.

Access token and refresh token shouldn't be stored in the local/session storage, because they are not a place for any sensitive data. Hence I would store the access token in a httpOnly cookie (even though there is CSRF) and I need it for most of my requests to the Resource Server anyway.

But what about the refresh token? I cannot store it in a cookie, because (1) it would be send with every request to my Resource Server as well which makes it vulnerable to CSRF too and (2) it would send expose both access/refresh token with an identical attack vector.

There are three solutions I could think of:


1) Storing the refresh token in an in-memory JavaScript variable, which has two drawbacks:

  • a) It's vulnerable to XSS (but may be not as obvious as local/session storage
  • b) It looses the "session" if a user closes the browser tab

Especially the latter drawback makes will turn out as a bad UX.


2) Storing the access token in session storage and sending it via a Bearer access_token authorization header to my resource server. Then I can use httpOnly cookies for the refresh token. This has one drawback that I can think of:

  • a) The refresh token is exposed to CSRF with every request made to the Resource Server.

3) Keep both tokens in httpOnly cookies which has the mentioned drawback that both tokens are exposed to the same attack vector.


Maybe there is another way or more than my mentioned drawbacks (please let me know), but in the end everything boils down to where do I keep my refresh token on the client-side? Is it httpOnly cookie or an in-memory JS variable? If it is the former, where do I put my access token then?

Would be super happy to get any clues about how to do this the best way from people who are familiar with the topic.

解决方案

You can store encrypted tokens securely in HttpOnly cookies.

https://medium.com/@sadnub/simple-and-secure-api-authentication-for-spas-e46bcea592ad

If you worry about long-living Refresh Token. You can skip storing it and not use it at all. Just keep Access Token in memory and do silent sign-in when Access Token expires.

Don't use Implicit flow because it's obsolete.

The most secure way of authentication for SPA is Authorization Code with PKCE.

In general, it's better to use existing libraries based on oidc-client than building something on your own.

这篇关于在哪里存储客户端上的刷新令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆