JWT vs Cookies,用于基于令牌的身份验证


112

我读了一些有关“ JWT vs Cookie”的帖子,但它们只会使我更加困惑。

  1. 我想澄清一下,当人们谈论“基于令牌的身份验证与cookie”时,此处的cookie仅指会话cookie?我的理解是cookie就像一种媒介,它可以用于实现基于令牌的身份验证(在客户端存储可以识别已登录用户的内容)或基于会话的身份验证(在客户端存储常量)与服务器端的会话信息匹配)

  2. 为什么我们需要JSON Web令牌?我使用标准cookie来实现基于令牌的身份验证(不使用会话ID,不使用服务器内存或文件存储Set-Cookie: user=innocent; preferred-color=azure:,我观察到的唯一区别是JWT既包含有效负载又包含签名 ...而您可以选择在HTTP标头的签名 Cookie 或纯文本 Cookie 之间。在我看来签署的cookie()cookie:'time=s%3A1464743488946.WvSJxbCspOG3aiGi4zCMMR9yBdvS%2B6Ob2f3OG6%2FYCJM'更节省空间,唯一的缺点是,客户端无法读取该令牌,只有能服务器...但我认为这是很好的,因为就像要求在智威汤逊是可选的,它不是必需的令牌有意义

Answers:


165

承载令牌和cookie之间的最大区别是浏览器将自动发送cookie,其中需要将承载令牌显式添加到HTTP请求。

此功能使cookie是保护网站安全的好方法,用户可以在其中登录并使用链接在页面之间导航。

自动发送Cookie的浏览器也有一个很大的缺点,那就是CSRF攻击。在CSRF攻击中,恶意网站会利用您的浏览器将身份验证cookie自动附加到该域的请求,并欺骗您的浏览器执行请求这一事实。

假设位于https://www.example.com的网站允许通过身份验证的用户通过POST将新密码设置为https://www.example.com/changepassword来更改其密码,而无需发布用户名或旧密码。

如果访问恶意网站时仍登录到该网站,该恶意网站在浏览器中加载了一个页面,并触发了该地址的POST,则浏览器将忠实地附加身份验证cookie,从而使攻击者可以更改密码。

Cookies也可以用于保护Web服务,但是如今,不记名令牌是最常用的。如果您使用cookie保护您的Web服务,则该服务必须存在于设置了身份验证cookie的域中,因为同源策略不会将cookie发送到另一个域。

而且,Cookie使得非基于浏览器的应用程序(例如从移动设备到平板电脑的应用程序)更难以使用您的API。


6
“如果您访问的恶意网站仍在登录该网站,该恶意网站在浏览器中加载了一个页面,从而触发了该地址的POST,则浏览器将忠实地附加身份验证cookie,从而使攻击者可以更改密码。” CORS不能防止这种情况吗?
kbuilds

17
@kbuilds仅是恶意页面使用AJAX张贴表单。如果攻击者让您单击常规表单上的“提交”按钮,则CORS不会起作用。
MvdD

3
但这是否意味着仅在不使用CSRF令牌的情况下该站点才容易受到攻击?
kbuild's

5
正确,您可以使用CSRF令牌减轻CSRF攻击。但这是您必须明确执行的操作。
MvdD

2
使用cookie可以保护您免受XSS攻击,但是要能够设置Authorization标头,您需要从javascript访问访问令牌;保护自己免受CSRF攻击很容易,但是XSS很难防御-不记名令牌更有意义,但是它附带有代价
kataik

101

总览

您想要的是从客户端向服务器发送JSON Web令牌(JWT)的cookie和承载令牌之间的区别。

Cookie和承载令牌都发送数据。

一个区别是cookie用于发送和存储任意数据,而承载令牌专门用于发送授权数据。

该数据通常被编码为JWT。

曲奇饼

Cookie是一个名称/值对,存储在Web浏览器中,并且具有到期日期和关联的域。

我们使用JavaScript或HTTP Response标头将cookie存储在Web浏览器中。

document.cookie = 'my_cookie_name=my_cookie_value'   // JavaScript
Set-Cookie: my_cookie_name=my_cookie_value           // HTTP Response Header

Web浏览器会自动将cookie和每个请求发送到cookie的域。

GET http://www.bigfont.ca
Cookie: my_cookie_name=my_cookie_value               // HTTP Request Header

不记名令牌

承载令牌是进入Authorization任何HTTP请求标头的值。它不会自动存储在任何地方,没有到期日期,也没有关联的域。这只是一个价值。我们将该值手动存储在客户端中,然后将该值手动添加到HTTP Authorization标头中。

GET http://www.bigfont.ca
Authorization: Bearer my_bearer_token_value          // HTTP Request Header

智威汤逊和基于令牌的身份验证

当我们进行基于令牌的身份验证(例如OpenID,OAuth或OpenID Connect)时,我们会从受信任的授权机构收到access_token(有时是id_token)。通常,我们要存储它,并将其与受保护资源的HTTP请求一起发送。我们该怎么做?

选项1是将令牌存储在cookie中。这将处理存储,并且还会在Cookie每个请求的标头中将令牌自动发送到服务器。然后,服务器解析cookie,检查令牌,然后做出相应的响应。

另一种选择是将令牌存储在本地/会话存储中,然后手动设置Authorization每个请求的标头。在这种情况下,服务器读取标头,然后像处理cookie一样继续进行。

值得阅读链接的RFC,以了解更多信息。


22

除了MvdD所说的有关自动发送Cookie的内容外:

  1. Cookie可以是一种媒介,但其最重要的功能是它与浏览器的交互方式。Cookie由服务器设置,并以非常特定的方式在请求中发送。另一方面,JWT仅是一种媒介,它是特定结构中某些事实的断言。如果您愿意,可以将JWT用作身份验证cookie。当您阅读比较它们的文章时,他们通常谈论的是使用前端代码和身份验证Cookie来作为承载令牌发送的JWT,该身份验证cookie对应于后端上的某些缓存的会话或用户数据。
  2. JWT提供了许多功能,并将它们置于标准中,以便可以在各方之间使用。JWT可以在许多不同地方充当某些事实的签名声明。Cookie,无论您输入了什么数据或对其进行签名,都只有在浏览器和特定后端之间使用才有意义。JWT可以在浏览器到后端之间使用,也可以在由不同方控制的后端之间使用(以OpenId Connect为例),也可以在一个方的后端服务中使用。关于您的已签名Cookie的特定示例,在该用例中,您可能可以实现与JWT相同的功能(“不使用会话ID,不使用服务器内存或文件存储”),但是您会失去对库的访问和同行评审该标准,除了CSRF问题中所讨论的其他答案。

总而言之:您正在阅读的帖子可能会将JWT作为承载令牌与身份验证cookie进行比较,以实现浏览器到服务器的身份验证。但是JWT可以做更多的事情,它带来了标准化和功能,可以在您可能想到的用例之外使用。


4
很好的说明了比较是承载令牌和cookie之间的比较。
肖恩·卢丁

14

尽管Cookie会随着请求一起自动发送而增加CSRF攻击的风险,但当Cookie出现以下情况时,它们可以降低XSS攻击的风险:HttpOnly,但由于设置标记,因为注入到页面中的任何脚本都无法读取Cookie。

CSRF:用户单击攻击者站点上的链接(或查看图像),这会使浏览器向受害者站点发送请求。如果受害者使用cookie,则浏览器将自动在请求中包含cookie,并且如果GET请求可能导致任何非只读操作,则受害者站点容易受到攻击。

XSS:攻击者在受害站点中嵌入了一个脚本(受害站点只有在未正确清理输入的情况下才容易受到攻击),并且攻击者的脚本可以执行允许页面执行的任何Java脚本。如果将JWT令牌存储在本地存储中,则攻击者的脚本可以读取这些令牌,并将这些令牌发送到他们控制的服务器。如果您将Cookie与该HttpOnly标志一起使用,则攻击者的脚本将无法读取您的Cookie。也就是说,他们成功注入的脚本仍将能够执行javascript可以执行的任何操作,因此您仍然受到IMO的控制(即,尽管他们可能无法读取Cookie并将其发送给自己的服务器以供以后使用) ,他们可以使用XHR将请求发送到vicitim网站,无论如何,该网站都将包含cookie。


2

参考- 需要JSON Web令牌

饼干

如果使用Cookie,则在对用户进行身份验证后,Gmail服务器将创建一个唯一的会话ID。对应于此会话ID,它将在Gmail中存储Gmail服务器用于识别用户并允许其执行操作所需的所有用户信息。
同样,对于所有后续请求和响应,此会话ID也将被传递。因此,现在服务器收到请求时,它将检查会话ID。使用此会话ID将检查是否有任何相应的信息。然后,它将允许用户访问资源并返回响应以及会话ID。

在此处输入图片说明

Cookie的缺点

  • Cookies /会话ID并非自包含。它是参考令牌。在每次验证期间,Gmail服务器都需要获取与其对应的信息。
  • 不适合涉及多个API和服务器的微服务架构

在此处输入图片说明

智威汤逊

  • JWT是独立的。这是一个价值代币。因此,在每次验证期间,Gmail服务器都不需要获取与其对应的信息。
  • 它是经过数字签名的,因此如果有人对其进行了修改,服务器将知道它
  • 最适合微服务架构
  • 它还有其他优点,例如指定到期时间。

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.