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

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

问题描述

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

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

我的问题:我将刷新令牌存储在客户端应用程序中的什么位置?关于此主题,关于SO的问题/答案很多,但是关于刷新令牌的答案尚不清楚

访问令牌和刷新令牌不应存储在本地/会话存储中,因为它们不是存放任何敏感数据的地方.因此,我会将访问令牌存储在 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/简单而安全的api认证,用于spas-e46bcea592ad

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

不要使用 Implicit 流,因为它是使用以下代码的身份验证代码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天全站免登陆