在React.js中将访问令牌存储在哪里? [英] Where to store access-token in react.js?
问题描述
我正在用Reactjs构建一个应用程序.验证access_token后,我必须进行访存调用.在注册时,从后端服务器获取access_token.但是,这些access_token存储在哪里.有什么方法可以使这些access_token全局化,以便所有组件都可以访问它.我已经使用了本地存储,缓存和会话存储,但不建议这样做. 在过去的几天中,此问题一直没有得到解决.提前致谢.
可用的选项和限制:
有两种存储令牌的选项:
- Web存储API :它提供2种机制:
sessionStorage
和localStorage
.此处存储的数据将始终对您的Javascript代码可用,并且无法从后端访问.因此,您将必须手动将其添加到例如标头中的请求中.此存储空间仅对您应用的域可用,而对子域不可用.这两种机制之间的主要区别在于数据有效期:
-
sessionStorage
:仅适用于会话的数据(直到浏览器或选项卡关闭). -
localStorage
:存储没有到期日期的数据,并且仅通过JavaScript或清除浏览器缓存/本地存储的数据来清除
- Cookies :与后续请求.您的Javascript代码的有效期和可见性可以控制.可以用于您应用的子域.
在设计身份验证机制时,您必须考虑两个方面:
出于安全考虑, OWASP 不建议在Web存储中存储敏感数据.您可以检查其 CheatSheetSeries 页.您还可以阅读此详细文章以了解更多详细信息.
其原因主要与XSS漏洞有关.如果您的前端没有100%不受XSS攻击的保护,则恶意代码可以在您的网页中执行,并且可以访问令牌. 要完全防XSS是非常困难的,因为它可能是由您使用的其中一种Javascript库引起的.
另一方面,如果将Cookie设置为HttpOnly
,则Javascript可能无法访问它们.
现在,Cookie的问题在于它们可以使您的网站容易受到CSRF的攻击. SameSite
cookie可以缓解这种类型的攻击.但是,较旧版本的浏览器不支持该类型的Cookie,因此可以使用其他方法,例如使用状态变量.在Auth0文档文章中进行了详细的介绍.
建议的解决方案:
为了安全地存储令牌,我建议您结合使用两个cookie,如下所述:
JWT令牌具有以下结构:header.payload.signature
通常,有效负载中会存在有用的信息,例如用户角色(可用于改编/隐藏UI的各个部分).因此,重要的是要使该部分对Javascript代码可用.
一旦完成身份验证流程并在后端创建了JWT令牌,其目的就是:
- 将
header.payload
部分存储在SameSite
Secure
Cookie中(因此只能通过https使用,但仍可用于JS代码) - 将
signature
部分存储在SameSite
Secure
HttpOnly
Cookie 中
- 在您的后端中实现一个中间件,以从这2个cookie中重建JWT令牌,并将其放在标头中:
Authorization: Bearer your_token
您可以设置Cookie的有效期,以满足您的应用程序要求.
在这篇文章,作者是Peter Locke.
I am building an app in Reactjs. I have to make fetch call, after verifying the access_token. On signup, access_token are acquired from back-end server. But, where to store these access_token. Is there any way of making these access_token global, so that all component can access it. I have used local storage, cache and session storage, but those are not advisable. Held up in this issue for past few days, any solutions for it. Thnks in advance.
Available options and limitations:
There are 2 types of options for storing your token:
- Web Storage API: which offers 2 mechanisms:
sessionStorage
andlocalStorage
. Data stored here will always be available to your Javascript code and cannot be accessed from the backend. Thus you will have to manually add it to your requests in a header for example. This storage is only available to your app's domain and not to sub domains. The main difference between these 2 mechanisms is in data expiry:
sessionStorage
: Data available only for a session (until the browser or tab is closed).localStorage
: Stores data with no expiration date, and gets cleared only through JavaScript, or clearing the Browser cache/Locally Stored Data
- Cookies: Automatically sent to your backend with the subsequent requests. Expiry and visibility to your Javascript code can be controlled. Can be available to your app's sub domains.
You have to consider 2 aspects when designing your authentication mechanism:
- Security: An access or identity token is a sensitive information. The main types of attacks to always consider are Cross Site Scripting (XSS) and Cross Site Request Forgery (CSRF).
- Functional requirements: Should the user stay logged in when the browser is closed? How long will be his session? etc
For security concerns, OWASP does not recommend storing sensitive data in a Web Storage. You can check their CheatSheetSeries page. You can also read this detailed article for more details.
The reason is mainly linked to the XSS vulnerability. If your frontend is not a 100% protected against XSS attacks then a malicious code can get executed in your web page and it would have access to the token. It is very difficult to be fully XSS-proof as it can be caused by one of the Javascript librairies you use.
Cookies on the other hand can be unaccessible to Javascript if they are set as HttpOnly
.
Now the problem with cookies is that they can easily make your website vulnerable to CSRF. SameSite
cookies can mitigate that type of attacks. However, older versions of browsers don't support that type of cookies so other methods are available such as the use of a state variable. It is detailed in this Auth0 documentation article.
Suggested solution:
To safely store your token, I would recommend that you use a combination of 2 cookies as described below:
A JWT token has the following structure: header.payload.signature
In general a useful information is present in the payload such as the user roles (that can be used to adapt/hide parts of the UI). So it's important to keep that part available to the Javascript code.
Once the authentication flow finished and JWT token created in the backend, the idea is to:
- Store the
header.payload
part in aSameSite
Secure
Cookie (so available only through https and still availble to the JS code) - Store the
signature
part in aSameSite
Secure
HttpOnly
Cookie - Implement a middleware in your backend to resconstruct the JWT token from those 2 cookies and put it in the header:
Authorization: Bearer your_token
You can set an expiry for the cookies to meet your app's requirements.
This idea was suggested and very well described in this article by Peter Locke.
这篇关于在React.js中将访问令牌存储在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!