处理 cookie 有其微妙之处,但从高层次来看,cookie 是您的 Web 服务器可以设置的一段数据,然后由用户的 Web 浏览器存储,并在将来出现任何请求时发送回服务器。只要 cookie 有效且适用于所发出的请求,浏览器就会向同一服务器发出请求。
(这就是为什么您不再需要使用 Angular 拦截器,因为浏览器本身可以确保发送 cookie)
除了一些特殊标志选项(例如仅 HTTP)之外,您还可以在更高级别将 cookie 设置为与给定域和路径关联。例如,您的服务器可以设置一个 cookie,这样浏览器稍后才会将其发送到在/api
path.
综上所述,cookie是HTTP的一种状态管理机制,参见相关RFC 2617 https://www.rfc-editor.org/rfc/rfc6265更多细节。
相比之下,JWT 只是一些具有众所周知的表示形式并遵循一些约定的数据。更具体地说,JWT 由标头、有效负载和签名部分组成,通常建议在大多数 JWT 用例中保持较小的有效负载大小。看JSON Web 令牌入门 https://auth0.com/learn/json-web-tokens/更多细节。
如果您阅读上一篇文章,您会注意到 JWT 的最终表示形式是三个用点分隔的 Base64url 编码字符串。这是特别令人感兴趣的,因为这意味着 JWT 非常适合在 HTTP 中使用,包括作为 cookie 的值。
需要记住的一件事是,根据规范,您只能保证浏览器将支持每个 cookie 最多 4096 字节的 cookie(通过 cookie 名称、值和属性的长度总和来衡量)。除非您在令牌中存储大量数据,否则您不应该遇到问题,但这始终是需要考虑的事情。是的,您还可以将 JWT 令牌分解为多个 cookie,但事情开始变得更加复杂。
此外,cookie 有其过期概念,因此请记住这一点,因为 JWT 本身在身份验证范围内使用时也会有自己的过期概念。
最后,我只想解决您对将 JWT 存储在中的一些担忧localStorage
/sessionStorage
。您是对的,如果您这样做,您必须了解其含义,例如,与存储关联的域内的任何 Javascript 代码都将能够读取令牌。然而,仅 HTTP 的 cookie 也不是灵丹妙药。我想读一下下面的文章:Cookie 与令牌:权威指南 https://dzone.com/articles/cookies-vs-tokens-the-definitive-guide.
它重点介绍传统会话标识符 cookie 与基于令牌 (JWT) 的身份验证系统之间的差异,该部分名为在哪里存储令牌?值得一读,因为它解决了存储的安全相关方面。
给 TL:DR 人员的总结:
网站面临的两个最常见的攻击媒介是跨站点
脚本编写 (XSS) 和跨站请求伪造(XSRF 或 CSRF)。当外部实体能够在您的网站或应用程序中执行代码时,就会发生跨站点脚本攻击。 (...)
如果攻击者可以在您的域上执行代码,您的 JWT 令牌(在本地存储中)是脆弱的。 (...)
如果您将 JWT 与本地存储结合使用,跨站点请求伪造攻击就不是问题。另一方面,如果您的用例要求您将 JWT 存储在 cookie 中,您需要防范 XSRF。
(重点是我的)