我是否必须在cookie或本地存储或会话中存储令牌?

Far*_*oro 18 javascript jwt

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

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

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

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

因此,当用户访问我的网站时,我会将其与他们匹配 req.sessionID,然后检索数据库中的数据,如购物车和用户会话.

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

第二个

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

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

 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);
        });
Run Code Online (Sandbox Code Playgroud)

结论是一切都与会话有关所以我可以用sessionID做所有事情?没有cookies或localstorage

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

Sap*_*asu 21

这个答案基于无状态方法,因此它没有谈论传统的会话管理

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

  1. 购物车 - 与业务功能更相关
  2. OAuth 2和JWT - 与安全性和身份验证相关

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

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

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

为了更好的理解,我建议你阅读使用OAuth 2.0规范一起.

更新于2019年2月16日

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

我认为浏览器localStoragesessionStorage没有为存储身份验证令牌提供足够的安全性的原因如下:

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

  2. localStorage并且sessionStorage不在子域之间共享.因此,如果我们在不同的子域上运行两个SPA,我们将无法获得SSO功能,因为一个应用程序存储的令牌将无法供组织内的其他应用程序使用.有一些解决方案正在使用iframe,但这些解决方案更像是解决方法,而不是一个好的解决方案

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

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

因此,即使我们使用SameSite__Secure-,我们也必须使用cookie来保证它.最重要的是,我们添加了如上所述的子域限制.

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

此外,由于cookie是sessionStorageSameSite,XSS脚本无法读取它.因此,XSS也得到了缓解.

  • @Kaiido 感谢您的反馈。但是使用这种方法,XSS 只能从用户的浏览器中做它打算做的任何伤害。远程模拟的可能性要小得多。 (2认同)
  • @BasilMusa 这里发生了两件事 - 1. cookie 不会随 HTTP 请求一起传输到攻击者的服务器,因为 cookie 域属性将与攻击者的服务器域不匹配,并且因为 cookie 是 `SameSite` cookie。2. 现在,由于 cookie 也是“httpOnly”,因此 XSS javascript 将无法从 cookie 中读取它并在 AJAX 请求中发送指纹值。 (2认同)

小智 9

LocalStorage/SessionStorage 容易受到 XXS 攻击。访问令牌可以被 JavaScript 读取。

带有 httpOnly、secure 和 SameSite=strict 标志的 Cookie 更安全。JavaScript 无法访问访问令牌及其有效负载。

但是,如果存在 XSS 漏洞,攻击者无论如何都可以以经过身份验证的用户身份发送请求,因为恶意脚本不需要读取 cookie 值,cookie 可以由浏览器自动发送。

这种说法是正确的,但风险不同。

使用cookies,访问令牌仍然是隐藏的,攻击者只能进行“现场”攻击。注入到 Web 应用程序中的恶意脚本可能受到限制,或者更改/注入更多脚本可能不是很容易。攻击者可能需要首先将用户或 Web 应用作为目标。这些条件限制了攻击的规模。

使用 localStorage,攻击者可以读取访问令牌并远程进行攻击。他们甚至可以与其他攻击者共享令牌并造成更严重的损害。如果攻击者设法在 CDN 中注入恶意脚本,比如谷歌字体 API,攻击者将能够从使用包含的 CDN 的所有网站中窃取访问令牌和 URL,并轻松找到新的目标。使用 localStorage 的网站更容易成为目标。

为了辩论

渗透测试可能会将您对敏感数据使用 localStorage 标记为风险。

如果 JavaScript 可以从 XSS 攻击中从 localStorage 读取访问令牌,那么您认为 httpOnly 标志为什么仍然被每个人推荐。

来自 OWASP 的推荐

不要将会话标识符存储在本地存储中,因为 JavaScript 始终可以访问数据。Cookie 可以使用 httpOnly 标志降低这种风险。

https://medium.com/@coolgk/localstorage-vs-cookie-for-jwt-access-token-war-in-short-943fb23239ca


归档时间:

查看次数:

11436 次

最近记录:

6 年,8 月 前