我是否必须在cookie或本地存储或会话中存储令牌? [英] Do I have to store tokens in cookies or localstorage or session?

查看:123
本文介绍了我是否必须在cookie或本地存储或会话中存储令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

抱歉,也许这是许多其他人提出的问题,但我真的很困惑,因为一些参考文献有很多不同的方法。

Sorry, maybe this is a question that many others have asked, but I am really confused because some references have many different ways.

Iam使用React SPA,Express,Express-session,Passport,JWT

Iam using React SPA, Express,Express-session, Passport,JWT

所以我'我对Cookies,Session和JWT / Passport感到困惑。

许多网站都使用cookie来存储购物车令牌。到目前为止,我已经根据会话ID存储了购物车数据而没有添加任何cookie。

Many websites use cookies to store shopping cart tokens. So far I have stored shopping cart data based on the session ID without adding any cookies.


所以当用户访问我的网站时,我会匹配用它们的
req.sessionID 然后检索数据库中的数据,如购物车和用户会话。

So when users visit my website, I will match it with their req.sessionID and then retrieve the data in the database like shopping carts and user session.

所以我的问题是我需要存储cookie吗?因为我可以通过req.sessionID访问它来获取所需的数据。

so my question is do I need to store cookies?because I can access it via req.sessionID to get the data needed.

第二个

我使用 passport-google-oauth20进行身份验证。成功登录后,数据将保存到会话中。并将其发送到客户端我必须通过URL查询?token ='sdsaxas'发送它。

I have made authentication using a passport-google-oauth20.After I successfully login, the data is saved into the session. and to send it to the client I have to send it via the URL query ?token='sdsaxas'.


在这种情况下,我得到了很多不同意见。有人将
保存到本地存储中,有人通过使用JWT将其转换为令牌将其保存为cookie。

in this case I get a lot of difference of opinion. someone saved it into local storage and someone saved it into cookies by converting it to a token using JWT.



 jwt.sign(
        payload,
        keys.jwt.secretOrPrivateKey, 
        {
            expiresIn:keys.jwt.expiresIn // < i dont know what is this expired for cookies or localstorage ?
        }, (err, token) => {

            res.redirect(keys.origin.url + "?token=" + token);
        });

结论是所有内容都与会话相关所以我可以使用sessionID完成所有操作?没有cookie或localstorage

只能通过执行一次或每次刷新页面并检索数据然后保存到redux中,因为我使用了React SPA

Only by doing fetch once or every page refresh and retrieving the data and then saved into redux because I use React SPA

推荐答案

这个答案是基于无国籍的方法,因此它没有谈及传统的会话管理

你问了两个完全不同的问题:

You have asked two altogether different questions:


  1. 购物车 - 这是更相关的商业功能

  2. OAuth 2& JWT - 与安全和身份验证相关

作为电子商务网站的用户,我希望我添加的任何项目在我上班回家后,当我从我的电脑上登录网站时,应该可以在购物车中使用我的移动设备上的购物车。因此,购物车数据应保存在后端数据库中并链接到我的用户帐户。

As an user of an ecommerce website, I'd expect that any item I add to my shopping cart from my mobile device while commuting to my workplace, should be available in the cart when I login to the website from my PC after reaching home. Therefore, the cart data should be saved in the back-end DB and linked to my user account.

使用OAuth 2.0进行身份验证时,JWT访问令牌和/或刷新令牌需要存储在客户端设备中的某个位置,以便一旦用户通过提供登录凭证来验证自己,他就不需要再次提供他的凭证来浏览网站。在这种情况下,浏览器本地存储,会话存储和cookie都是有效的选项。但请注意,此处cookie未链接到服务器端的任何会话。换句话说,cookie不存储任何会话ID。 cookie仅用作访问令牌的存储,它随每个http请求传递给服务器,然后服务器使用数字签名验证令牌,以确保它不被篡改且未过期。

When it comes to authentication using OAuth 2.0, the JWT access token and / or refresh token need to be stored somewhere in the client device, so that once the user authenticates himself by providing login credentials, he doesn't need to provide his credentials again to navigate through the website. In this context, the browser local storage, session storage and cookies are all valid options. However, note that here the cookie is not linked to any session on the server side. In other words, the cookie doesn't store any session id. The cookie is merely used as a storage for access token which is passed to the server with every http request and the server then validates the token using the digital signature to ensure that it is not tampered and it is not expired.

尽管访问和/或刷新令牌的所有三个存储选项都很受欢迎,但在正确使用时,cookie似乎是最安全的选项。

Although all three storage options for access and / or refresh tokens are popular, cookie seems to be the most secured option when used in the correct way.

为了更好地理解这一点,我建议你阅读这个以及OAuth 2.0规范。

To understand this better, I recommend you read this and this along with the OAuth 2.0 specification.

我之前说过,cookie似乎是最安全的选择。我想进一步澄清这一点。

I said earlier that cookie seems to be the most secured options. I'd like to further clarify the point here.

我认为浏览器 localStorage 和<$ c $的原因c> sessionStorage 没有为存储身份验证令牌提供足够的安全性如下:

The reason I think browser localStorage and sessionStorage do not provide enough security for storing auth tokens are as follows:


  1. 如果是XSS发生这种情况时,恶意脚本可以从那里轻松读取令牌并将其发送到远程服务器。有人在远程服务器或攻击者冒充受害用户时没有问题。

  1. If XSS occurs, the malicious script can easily read the tokens from there and send them to a remote server. There on-wards the remote server or attacker would have no problem in impersonating the victim user.

localStorage sessionStorage 不在子域之间共享。因此,如果我们在不同的子域上运行两个SPA,我们将无法获得SSO功能,因为一个应用程序存储的令牌将无法供组织内的其他应用程序使用。有些解决方案使用 iframe ,但这些解决方案更像是解决方法,而不是一个好的解决方案。当使用响应标头 X-Frame-Options 来避免使用 iframe 进行点击劫持攻击时,任何解决方案都带有 iframe 是不可能的。

localStorage and sessionStorage are not shared across sub-domains. So, if we have two SPA running on different sub-domains, we won't get the SSO functionality because the token stored by one app won't be available to the other app within the organization. There are some solutions using iframe, but those look more like workarounds rather than a good solution. And when the response header X-Frame-Options is used to avoid clickjacking attacks with iframe, any solution with iframe is out of question.

但是,这些风险可以通过使用指纹缓解(如 OWASP JWT中所述)备忘单)又需要一个cookie。

These risks can, however, be mitigated by using a fingerprint (as mentioned in OWASP JWT Cheat Sheet) which again in turn requires a cookie.

指纹的想法是,生成一个加密强大的随机字节串。然后,原始字符串的Base64字符串将存储在 HttpOnly 安全 SameSite中名称前缀 __ Secure - 的cookie。应根据业务需求使用域和路径属性的正确值。字符串的SHA256哈希也将在JWT的声明中传递。因此,即使XSS攻击将JWT访问令牌发送给攻击者控制的远程服务器,它也无法在cookie中发送原始字符串,因此服务器可以根据cookie的缺失拒绝该请求。 XSS脚本无法读取 HttpOnly 的cookie。

The idea of fingerprint is, generate a cryptographically strong random string of bytes. The Base64 string of the raw string will then be stored in a HttpOnly, Secure, SameSite cookie with name prefix __Secure-. Proper values for Domain and Path attributes should be used as per business requirement. A SHA256 hash of the string will also be passed in a claim of JWT. Thus even if an XSS attack sends the JWT access token to an attacker controlled remote server, it cannot send the original string in cookie and as a result the server can reject the request based on the absence of the cookie. The cookie being HttpOnly cannot be read by XSS scripts.

因此,即使我们使用 localStorage sessionStorage ,我们必须使用cookie来保证安全。最重要的是,我们添加了如上所述的子域限制。

Therefore, even when we use localStorage and sessionStorage, we have to use a cookie to make it secured. On top of that, we add the sub-domain restriction as mentioned above.

现在,使用cookie存储JWT的唯一问题是CSRF攻击。由于我们使用 SameSite cookie,因此可以减轻CSRF,因为跨站点请求(AJAX或仅通过超链接)是不可能的。如果该站点在任何旧浏览器或其他不支持 SameSite cookie的不那么流行的浏览器中使用,我们仍然可以通过另外使用加密的CSRF cookie来缓解CSRF强随机值,以便每个AJAX请求读取cookie值并在自定义HTTP标头中添加cookie值(GET和HEAD请求除外,这些请求不应进行任何状态修改)。由于CSRF由于相同的原始策略而无法读取任何内容,并且它基于利用POST,PUT和DELETE等不安全的HTTP方法,因此CSRF cookie将降低CSRF风险。所有现代SPA框架都使用这种使用CSRF cookie的方法。提到Angular方法此处

Now, the only concern about using a cookie to store JWT is, CSRF attack. Since we use SameSite cookie, CSRF is mitigated because cross-site requests (AJAX or just through hyperlinks) are not possible. If the site is used in any old browser or some other not so popular browsers that do not support SameSite cookie, we can still mitigate CSRF by additionally using a CSRF cookie with a cryptographically strong random value such that every AJAX request reads the cookie value and add the cookie value in a custom HTTP header (except GET and HEAD requests which are not supposed to do any state modifications). Since CSRF cannot read anything due to same origin policy and it is based on exploiting the unsafe HTTP methods like POST, PUT and DELETE, this CSRF cookie will mitigate the CSRF risk. This approach of using CSRF cookie is used by all modern SPA frameworks. The Angular approach is mentioned here.

此外,由于cookie是 httpOnly 安全,因此XSS脚本无法读取它。因此,XSS也得到了缓解。

Also, since the cookie is httpOnly and Secured, XSS script cannot read it. Thus XSS is also mitigated.

值得一提的是,使用适当的 content-security-policy可以进一步减轻XSS和脚本注入的速度响应标题。

It may be also worth mentioning that XSS and script injection can be further mitigated by using appropriate content-security-policy response header.

这篇关于我是否必须在cookie或本地存储或会话中存储令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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