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

I want some clarification, when people talking about "token-based authentication vs cookies", cookies here merely refer to session cookies? My understanding is that cookie is like a medium, it can be used to implement a token-based authentication(store something that can identify logged-in user on the client side) or a session-based authentication(store a constant on the client side that matches session information on the server side) Why do we need JSON web token? I was using the standard cookie to implement token-based authentication(not using session id, not use server memory or file storage): Set-Cookie: user=innocent; preferred-color=azure, and the only difference that I observed is that JWT contains both payload and signature...whereas you can choose between signed or plaintext cookie for http header. In my opinion signed cookie (cookie:'time=s%3A1464743488946.WvSJxbCspOG3aiGi4zCMMR9yBdvS%2B6Ob2f3OG6%2FYCJM') is more space efficient, the only drawback is that client cannot read the token, only the server can...but I think it's fine because just like claim in JWT is optional, it's not necessary for token to be meaningful


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

这一特性使cookie成为保护网站安全的好方法,用户可以通过链接登录和在页面之间导航。

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

假设https://www.example.com网站允许经过身份验证的用户通过POST-ing新密码到https://www.example.com/changepassword来更改密码,而不需要发布用户名或旧密码。

如果你在访问恶意网站时仍然登录该网站,该网站在你的浏览器中加载了一个页面,触发了对该地址的POST,你的浏览器会忠实地附加身份验证cookie,允许攻击者更改你的密码。

cookie也可以用来保护web服务,但现在最常用的是不记名令牌。如果您使用cookie来保护您的web服务,该服务需要存在于设置了身份验证cookie的域上,因为同源策略不会将cookie发送到另一个域。

此外,cookie使得非基于浏览器的应用程序(如移动到平板电脑应用程序)更难使用您的API。


除了MvdD所说的自动发送cookie:

A cookie can be a medium, but its most significant function is how it interacts with the browser. Cookies are set by the server and sent in requests in very specific ways. JWT on the other hand is exclusively a medium, it is an assertion of some facts in a particular structure. If you were so inclined, you could put a JWT as your authentication cookie. When you read articles comparing them, they typically are talking about using a JWT sent as a bearer token by front end code vs an authentication cookie which corresponds to some cached session or user data on the back end. JWT offers many features, and puts them in a standard so they can be used between parties. A JWT can act as a signed assertion of some facts in many different places. A cookie, no matter what data you put in it or if you sign it, only really makes sense to use between a browser and a specific back end. JWT can be used from browser to back end, between back ends controlled by different parties (OpenId Connect is an example), or within back end services of one party. Regarding your specific example of your signed cookies, you can probably achieve the same functions ("not using session id, not use server memory or file storage") as JWT in that use case, but you lose out on libraries and peer-review of the standard, in addition to the CSRF issues talked about in the other answer.

总之:您正在阅读的文章可能将JWT作为承载令牌与用于浏览器到服务器身份验证目的的身份验证cookie进行比较。但是JWT可以做的更多,它为你可能想到的用例之外的使用带来了标准化和特性。


概述

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

cookie和不记名令牌都发送数据。

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

这些数据通常被编码为JWT。

饼干

cookie是存储在web浏览器中的名称-值对,具有有效日期和相关域。

我们用JavaScript或HTTP响应头将cookie存储在web浏览器中。

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

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

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

不记名的令牌

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

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

JWT和基于令牌的身份验证

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

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

选项2是将令牌存储在本地/会话存储中,然后手动设置每个请求的授权头。在这种情况下,服务器像处理cookie一样读取报头并继续处理。

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


虽然cookie会由于随请求一起自动发送而增加CSRF攻击的风险,但当设置HttpOnly标志时,它们可以降低XSS攻击的风险,因为注入到页面中的任何脚本都无法读取cookie。

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

XSS: an attacker embeds a script in the victim site (the victim site is only vulnerable if inputs are not sanitized correctly), and the attacker's script can do anything JavaScript is allowed to do on the page. If you store JWT tokens in local storage, the attacker's script could read those tokens, and also send those tokens to a server they control. If you use cookies with the HttpOnly flag, the attacker's script won't be able to read your cookie to begin with. That said, the script they successfully injected will still be able to do anything JavaScript can do, so you're still hosed IMO (i.e., while they may not be able to read the cookie to send it off to their own server for use later, they can send requests to the victim site using XHR, which will include the cookie anyway).


参考-需要JSON Web令牌

饼干

In case of cookies, once the user has been authenticated then the Gmail Server will create a unique session Id. Corresponding to this session id it will store in memory all the user information that is needed by the Gmail server for recognizing the user and allowing it perform operations.
Also then for all subsequent requests and response, this session id will also be passed. So now when the server receives a request it will check the session id. Using this session id will check if there is any corresponding information. It will then allow the user to access the resource and return back the response along with the session id.

cookie的缺点

Cookies/session id不是自包含的。它是一个引用令牌。在每次验证期间,Gmail服务器需要获取与之对应的信息。 不适合涉及多个API和服务器的微服务架构

JWT

JWT是独立的。它是一个价值令牌。因此,在每次验证期间,Gmail服务器不需要获取与之对应的信息。 它是数字签名的,所以如果有人修改它,服务器就会知道它 它最适合微服务架构 它还有其他优点,比如指定过期时间。


是的,cookie可以用于任何事情。 为什么我们需要智威汤逊?

JSON是最好的(也是唯一需要的)数据格式,你可以在其中放入任何你想要的东西。

使用JWT,您不受数据大小的限制,使用cookie,您每个域只有4093个字节-对于所有cookie,而不是一个。