Cookie、Session、Token 之间有什么区别?

Cookie 存储在浏览器(客户端),生命周期可以由服务器端设置。

Session 存储在服务器,生命周期由服务器端控制(在默认情况下,当用户关闭浏览器时,Session结束)。

**性能:**使用Cookie时,因为数据随每个请求发送到服务器,可能会影响网络传输效率,尤其是在Cookie数据较大时。使用Session时,因为数据存储在服务器端,每次请求都需要查询服务器上的Session数据,这可能会增加服务器的负载,特别是在高并发场景下。

Token(如JWT)存储在客户端,是一个加密的令牌,可以跨多个会话使用。

简单来说,Cookie 和 Session 更适合用于单次会话的认证和状态管理,而 Token 更适合用于跨会话的认证和状态管理。

携带Cookie的HTTP请求是有状态还是无状态的?Cookie是HTTP协议簇的一部分,那为什么还说HTTP是无状态的?

HTTP被描述为“无状态”的主要原因是每个HTTP请求都是独立的,服务器并不保存关于客户端的状态信息,每个请求都需要提供足够的信息来理解请求的意图。

虽然Cookie是HTTP协议簇的一部分,但是HTTP协议在设计初衷上仍然保持无状态特性,即每个请求都是相互独立的。使用Cookie只是在无状态协议下的一种补充机制,用于在客户端存储状态信息以实现状态保持。

可以说即使HTTP本身是无状态的协议,但通过Cookie的使用可以实现一定程度的状态保持功能。

如果我把数据存储到 LocalStorage,和Cookie有什么区别?

  • 存储容量:Cookie 的存储容量通常较小,每个 Cookie 的大小限制在几 KB 左右。而 Localstorage 的存储容量通常较大,一般限制在几 MB 左右。因此,如果需要存储大量数据,LocalStorage 通常更适合;
  • 数据发送:Cookie 在每次 HTTP 请求中都会自动发送到服务器,这使得 Cookie 适合用于在客户端和服务器之间传递数据。而 Localstorage 的数据不会自动发送到服务器,它仅在浏览器端存储数据,因此LocalStorage 适合用于在同一域名下的不同页面之间共享数据;
  • 生命周期:Cookie 可以设置一个过期时间,使得数据在指定时间后自动过期。而 LocalStorage 的数据将永久存储在浏览器中,除非通过 JavaScript 代码手动删除;
  • 安全性:Cookie 的安全性较低,因为 Cookie 在每次 HTTP 请求中都会自动发送到服务器,存在被窃取或篡改的风险。而 LocalStorage 的数据仅在浏览器端存储,不会自动发送到服务器,相对而言更安全一些;

JWT 令牌和传统方式有什么区别?

  • 无状态性:JWT是无状态的令牌,不需要在服务器端存储会话信息。相反,JWT令牌中包含了所有必要的信息,如用户身份、权限等。这使得JWT在分布式系统中更加适用,可以方便地进行扩展和跨域访问。
  • 安全性:JWT使用密钥对令牌进行签名,确保令牌的完整性和真实性。只有持有正确密钥的服务器才能对令牌进行验证和解析。这种方式比传统的基于会话和Cookie的验证更加安全,有效防止了CSRF(跨站请求伪造)等攻击。
  • 跨域支持:JWT令牌可以在不同域之间传递,适用于跨域访问的场景。通过在请求的头部或参数中携带JWT令牌,可以实现无需Cookie的跨域身份验证。

JWT 令牌都有哪些字段?

JWT令牌由三个部分组成:头部(Header)、载荷(Payload)和签名(Signature)。其中,头部和载荷均为JSON格式,使用Base64编码进行序列化,而签名部分是对头部、载荷和密钥进行签名后的结果。

JWT结构

JWT 令牌为什么能解决集群部署,什么是集群部署?

JWT令牌通过在令牌中包含所有必要的身份验证和会话信息,使得服务器无需存储会话信息,从而解决了集群部署中的身份验证和会话管理问题。当用户进行登录认证后,服务器将生成一个JWT令牌并返回给客户端。客户端在后续的请求中携带该令牌,服务器可以通过对令牌进行验证和解析来获取用户身份和权限信息,而无需访问共享的会话存储。
由于JWT令牌是自包含的,服务器可以独立地对令牌进行验证,而不需要依赖其他服务器或共享存储。这使得集群中的每个服务器都可以独立处理请求,提高了系统的可伸缩性和容错性。

JWT 的缺点是什么?

JWT一旦派发出去,在失效之前都是有效的,没办法即使撤销JWT。

要解决这个问题的话,得在业务层增加判断逻辑,比如增加黑名单机制。使用内存数据库比如Redis维护一个黑名单,如果想让某个JWT失效的话就直接将这个JWT加入到黑名单即可。然后,每次使用JWT进行请求的话都会先判断这个JWT是否存在于黑名单中。

JWT 令牌如果泄露了,怎么解决,JWT是怎么做的?

  • 及时失效令牌:当检测到JWT令牌泄露或存在风险时,可以立即将令牌标记为失效状态。服务器在接收到带有失效标记的令牌时,会拒绝对其进行任何操作,从而保护用户的身份和数据安全。
  • 刷新令牌:JWT令牌通常具有一定的有效期,过期后需要重新获取新的令牌。当检测到令牌泄露时,可以主动刷新令牌,即重新生成一个新的令牌,并将旧令牌标记为失效状态。这样,即使泄露的令牌被恶意使用,也会很快失效,减少了被攻击者滥用的风险。
  • 使用黑名单:服务器可以维护一个令牌的黑名单,将泄露的令牌添加到黑名单中。在接收到令牌时,先检查令牌是否在黑名单中,如果在则拒绝操作。这种方法需要服务器维护黑名单的状态,对性能有一定的影响,但可以有效地保护泄露的令牌不被滥用。

前端如何存储JWT?

Local Storage(本地存储)

  • 优点:Local Storage 提供了较大的存储空间(一般为5MB),且不会随着HTTP请求一起发送到服务器,因此不会出现在HTTP缓存或日志中。
  • 缺点:存在**XSS(跨站脚本攻击)**的风险,恶意脚本可以通过JavaScript访问到存储在Local Storage中的JWT,从而盗取用户凭证。

Session Storage(会话存储)

  • 优点:与Local Storage类似,但仅限于当前浏览器窗口或标签页,当窗口关闭后数据会被清除,这在一定程度上减少了数据泄露的风险。
  • 缺点:用户体验可能受影响,因为刷新页面或在新标签页打开相同应用时需要重新认证。
  • 优点:可以设置HttpOnly标志来防止通过JavaScript访问,减少XSS攻击的风险;可以利用Secure标志确保仅通过HTTPS发送,增加安全性。
  • 缺点:大小限制较小(通常4KB),并且每次HTTP请求都会携带Cookie,可能影响性能;设置不当可能会受到**CSRF(跨站请求伪造)**攻击。