在 cookie 中存储 Bearer 令牌的安全性
Posted
技术标签:
【中文标题】在 cookie 中存储 Bearer 令牌的安全性【英文标题】:Security of storing Bearer token in cookies 【发布时间】:2019-03-05 13:25:13 【问题描述】:我的 SPA 使用 React 作为前端,使用 laravel API 作为后端。
当用户登录时(通过 axios 和 api),api 返回一个访问(Bearer token)作为响应。我使用 react-cookie 框架将访问令牌作为 cookie 存储在浏览器中。此 cookie 将被读取并用于任何未来的请求。
这是正确的做法吗? cookie 数据不就是浏览器中任何攻击者都可以轻松获取的东西吗?因为它只是某处计算机的文件。
是什么阻止了攻击者获取该 cookie、冒充该用户并开始执行需要身份验证的操作?
令牌的寿命可以说是 1 年。它只会在用户每次登录时刷新。我知道如果我将寿命设置得更短,它会更安全。但是,这是否意味着用户必须不断登录?
-----更新-----
我不确定提供的任何解决方案是否回答了我的问题。 SPA 应用程序是基于前端的,请求可以来自任何地方,例如邮递员、移动应用程序或任何希望与我的支持服务器通信的第三方设备。因此,这些设备需要一种方法来在本地存储一些访问令牌以用于将来的任何请求。
我知道这可能发生的唯一方法是让我的服务器向请求者发送一些身份验证令牌并将其存储在某个地方以用于下一个请求。
在这种情况下,我不确定 CSRF 令牌或任何其他方式是否有助于解决我的问题?
就像 facebook,如果我清除缓存,我将不得不重新登录。这意味着 Facebook 正在我的定位计算机上存储一些内容,以便下次我可以自动进行身份验证
【问题讨论】:
【参考方案1】:您的 JS 不应访问 cookie。您可以在 cookie 上设置一些标志,以帮助保护它们并确保它们仅用于正确的目的。
HttpOnly 标志设置在 cookie 上,然后 JS 将无法访问它,但仍会随任何请求一起发送。
SameSite 标志将确保仅将 cookie 发送回给您的站点。这可以防止泄漏。
Secure 标志将使其仅通过安全连接发送 cookie,以防止有人从您的网络流量中嗅出它。
编辑
您可能想要查找授权工作流程,但其要点如下:
-
用户使用用户名和密码登录
从后端登录时会发出 JSON Web 令牌并发送到浏览器
JWT(JSON Web 令牌)可以存储在浏览器的 Web 存储(本地/会话存储)中的 cookie 中
对 REST API 的后续请求将在标头或查询字符串中嵌入令牌以进行授权。通过这种形式的授权,您的 REST API 可以根据授权级别了解发出请求的人以及要返回的资源类型
请查看@tpopov 的回答,因为他也提出了一些非常好的观点。
【讨论】:
【参考方案2】:我只是想补充一些在 cookie 中存储令牌的缺点,你也应该知道:
cookie 的最大大小仅为 4kb,因此如果 您有许多附加到令牌的声明。
Cookie 容易受到跨站请求伪造(CSRF 或 XSRF) 攻击。使用 Web 应用程序框架的 CSRF 保护使 cookies 是存储 JWT 的安全选项。 CSRF 也可以部分 通过检查 HTTP Referer 和 Origin 标头来防止。你可以 还设置 SameSite=strict cookie 标志以防止 CSRF 攻击。
如果应用程序需要,可能难以实施 跨域访问。 Cookie 具有附加属性(域/路径) 可以修改以允许您指定 cookie 的位置 允许发送。
------- 更新-----
您还可以使用 cookie 来存储身份验证令牌,甚至更好(至少在我看来比使用本地存储或 Redis 等会话中间件)。如果我们把 httpOnly 和安全标志放在一边,还有一些不同的方法可以控制 cookie 的生命周期:
cookies 可以在浏览器关闭后销毁(会话 饼干)。 实施服务器端检查(通常由 使用的 web 框架),您可以实现过期或滑动窗口过期。 Cookie 可以是持久的(不会被销毁) 浏览器关闭后)过期。【讨论】:
以上是关于在 cookie 中存储 Bearer 令牌的安全性的主要内容,如果未能解决你的问题,请参考以下文章
Nuxt Apollo 模块请求授权标头,带有双 'Bearer'
将 WebAPI JWT 访问令牌作为加密的 FormsAuthenticationTicket 存储在 Response.Cookies 中是不是安全(在 asp.net mvc 中)