我读了一些关于“JWT vs Cookie”的帖子,但它们只让我更加困惑......
我想要一些澄清,当人们谈论“基于令牌的身份验证与Cookie”, Cookie 时,这里只是指 会话饼干的?我的理解是 cookie就像一个中等,它可以用来实现基于令牌的身份验证(存储可以在客户端识别登录用户的东西)或基于会话的身份验证(在客户端存储与服务器端的会话信息相匹配的常量)
为什么我们需要 JSON网络令牌?我使用标准cookie来实现基于令牌的身份验证(不使用会话ID,不使用服务器内存或文件存储):import pandas as pd
from openpyxl import load_workbook
book = load_workbook('Abc.xlsx')
writer = pd.ExcelWriter('Abc.xlsx', engine='openpyxl')
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
df.Manufacturer.value_counts().to_frame().to_excel(writer, sheet_name='Categories')
writer.save()
,我观察到的唯一区别是JWT包含有效负载和签名 ...而您可以在http标头的 signed或plaintext Cookie之间进行选择。在我看来,签名cookie(Set-Cookie: user=innocent; preferred-color=azure
)更节省空间,唯一的缺点是客户端无法读取令牌,只有服务器可以...但我认为它很好,因为就像声明在JWT中是可选的,令牌没有必要有意义
答案 0 :(得分:80)
承载令牌和cookie之间的最大区别在于浏览器将 自动发送cookie ,其中需要将明确的加载令牌添加到HTTP请求中。
此功能使Cookie成为保护网站安全的好方法,用户使用链接登录并在页面之间导航。
浏览器自动发送cookie也有很大的缺点,即CSRF次攻击。在CSRF攻击中,恶意网站利用了这样一个事实:您的浏览器会自动将身份验证cookie附加到该域的请求,并诱使您的浏览器执行请求。
假设https://www.example.com处的网站允许经过身份验证的用户通过POST
更改密码 - 将新密码更改为https://www.example.com/changepassword,而无需发布用户名或旧密码。
如果您在访问恶意网站时仍然登录该网站,该网站会在您的浏览器中加载触发POST到该地址的页面,您的浏览器将忠实地附加身份验证Cookie,允许攻击者更改您的密码。
Cookie也可用于保护Web服务,但现在最常使用的是承载令牌。如果您使用cookie来保护您的Web服务,则该服务需要存在于设置了身份验证cookie的域中,因为same-origin policy不会将cookie发送到其他域。
此外,Cookie使非基于浏览器的应用程序(如移动设备到平板电脑应用程序)更难以使用您的API。
答案 1 :(得分:47)
您要求的是用于将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
网络浏览器会自动向Cookie的每个请求发送Cookie。
GET http://www.bigfont.ca
Cookie: my_cookie_name=my_cookie_value // HTTP Request Header
承载令牌是一个进入任何HTTP请求的Authorization
标头的值。它不会自动存储在任何地方,它没有到期日期,也没有关联的域。它只是一个价值。我们在客户端手动存储该值,并手动将该值添加到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以了解更多信息。
答案 2 :(得分:9)
除了MvdD所说的有关自动发送cookie的内容之外:
总结:您正在阅读的帖子可能是将JWT作为承载令牌与用于浏览器到服务器身份验证的身份验证Cookie进行比较。但是JWT可以做得更多,它带来了标准化和功能,可以在您可能正在考虑的用例之外使用。
答案 3 :(得分:6)
答案 4 :(得分:0)
虽然cookie随请求一起自动发送 会增加CSRF攻击的风险,但是当设置HttpOnly
标志时,它们可以降低XSS攻击的风险,因为注入页面的任何脚本都将无法读取Cookie。
CSRF:用户单击攻击者网站上的链接(或查看图像),这导致浏览器向受害者的网站发送请求。如果受害者使用cookie,则浏览器将自动在请求中包含cookie,并且如果GET请求可能导致任何非只读操作,则受害者站点很容易受到攻击。
XSS:攻击者将脚本嵌入受害者站点中(只有在未正确清理输入的情况下,受害者站点才容易受到攻击),并且攻击者的脚本可以执行允许页面上执行的javascript操作。如果将JWT令牌存储在本地存储中,则攻击者的脚本可以读取这些令牌,并将这些令牌发送到其控制的服务器。如果您使用带有HttpOnly
标志的cookie,则攻击者的脚本将无法读取您的cookie。也就是说,他们成功注入的脚本仍将能够执行javascript可以执行的任何操作,因此您仍然受到IMO的控制(即,尽管他们可能无法读取Cookie并将其发送给自己的服务器以供以后使用) ,他们可以使用XHR将请求发送到vicitim站点,该站点仍将包含cookie。