Cookie,Session,Token,JWT
Cookie
存储位置:Cookie数据存储在客户端(用户的浏览器)上。
数据传输:每次向同一服务器发送请求时,Cookie数据都会自动加在请求头中发送给服务器。
容量限制:Cookie有大小限制(每个域名下大约为4KB),并且浏览器限制每个域名下的Cookie数量。
安全性:由于存储在客户端,容易被用户删除和篡改,因此安全性相对较低。敏感信息不应存储在Cookie中。
生命周期:Cookie可以设置过期时间。如果不设置,生命周期默认为浏览器会话期间;设置了过期时间后,即使关闭浏览器,Cookie也会保留到指定的时间。
session
存储位置:Session数据存储在服务器上。
数据传输:服务器为每个用户的会话分配一个唯一的Session ID,而Session ID通常通过Cookie在客户端和服务器之间传递。用户的所有请求都会携带这个Session ID,服务器据此识别用户。
容量限制:Session理论上没有大小限制,可以存储较大量的数据。
安全性:由于存储在服务器上,安全性相对较高。但需要正确处理Session ID的传输,防止会话劫持等安全问题。
生命周期:Session的生命周期通常由服务器控制,可以基于一段时间的不活动自动过期,或者由服务器端的逻辑显式销毁。
session 认证流程
用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session, 并生成一个
sessionId
将
sessionId
保存cookie
中并返回给浏览器当用户第二次访问服务器的时候,会自动携带设置的
cookie
传给服务器服务器接收到客户端传回的
cookie
获取到其中的sessionId
,再根据SessionID
查找对应的Session
信息进行身份验证
注意点
将 session 存储在服务器里面,当用户同时在线量比较多时,这些 session 会占据较多的内存,需要在服务端定期的去清理过期的 session
当网站采用集群部署的时候,会遇到多台 web 服务器之间如何做 session 共享的问题。因为 session 是由单个服务器创建的,但是处理用户请求的服务器不一定是那个创建 session 的服务器,那么该服务器就无法拿到之前已经放入到 session 中的登录凭证之类的信息了。
Cookie 和 Session 的区别
存储位置:Cookie存储在客户端,Session存储在服务器。
保存的数据格式与大小也不同
安全性:Session比Cookie安全,因为数据存储在服务器端。
生命周期管理:Cookie的生命周期可以由客户端控制或定义,Session的生命周期由服务器管理。
性能考量:每次HTTP请求都会携带Cookie,可能会影响性能;而Session需要服务器持续跟踪状态,也会消耗服务器资源。
用途差异:Cookie常用于保存用户偏好、跟踪用户行为;Session更适合存储敏感信息、用户登录状态等。
Token
Token是一个广义的概念,它代表了一个系统生成的字符串,用于标识用户的登录会话或进行身份验证。Token可以采取任何格式,不限于特定的数据结构
一般Token由以下元素组:
uid:用户唯一的身份标识
time:当前时间的时间戳
sign:签名
Token的特点:
服务端无状态化,可扩展性好
支持移动端设备
支持跨程序调用
token 的身份验证流程:
客户端使用用户名跟密码请求登录
服务端收到请求,去验证用户名与密码
验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端
客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里
客户端每次向服务端请求资源的时候需要带着服务端签发的 token
服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据
服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据
基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据。用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库
token 完全由应用管理,所以它可以避开同源策略
Refresh Token
Refresh Token是在现代身份验证协议中使用的一个概念,主要用于在用户的访问令牌(Access Token)过期后,安全地获取新的访问令牌,而无需用户再次登录。它是OAuth 2.0和OpenID Connect等身份验证框架中的一个重要组成部分
工作原理
在使用Refresh Token的身份验证流程中,当用户成功登录后,身份验证服务器会同时返回一个访问令牌(Access Token)和一个刷新令牌(Refresh Token):
访问令牌(Access Token):用于访问受保护的资源,如API调用。访问令牌具有较短的有效期,通常设定为几分钟到几小时不等。
刷新令牌(Refresh Token):用于在访问令牌过期后获取新的访问令牌。刷新令牌具有较长的有效期,通常比访问令牌长得多。
当访问令牌过期后,应用可以使用刷新令牌向身份验证服务器请求一个新的访问令牌。这个过程可以在用户不知情的情况下自动进行,从而提供无缝的用户体验。一旦新的访问令牌被颁发,旧的访问令牌通常会被废弃。
优点
提高安全性:由于访问令牌具有较短的有效期,即使被泄露,其潜在的风险也相对较低。刷新令牌虽然有效期更长,但仅用于与身份验证服务器通信,不用于访问受保护资源。
提升用户体验:用户无需频繁登录,即可保持长时间的会话,尤其适用于移动应用和单页应用(SPA)。
安全注意事项
保护刷新令牌:由于刷新令牌可以用来获取新的访问令牌,因此需要确保其安全性,避免泄露。
令牌撤销:系统应支持撤销刷新令牌的功能,以应对刷新令牌被泄露或用户登出的情况。
限制使用范围:最好限制刷新令牌的使用范围,比如只能从特定的设备或IP地址使用刷新令牌获取新的访问令牌。
JWT
JWT是Token的一种实现方式
JWT 认证流程:
用户输入用户名/密码登录,服务端认证成功后,会返回给客户端一个 JWT
客户端将 token 保存到本地(通常使用 localstorage,也可以使用 cookie)
当用户希望访问一个受保护的路由或者资源的时候,需要请求头的 Authorization 字段中使用Bearer 模式添加 JWT,其内容看起来是下面这样
Authorization: Bearer复制代码
服务端的保护路由将会检查请求头 Authorization 中的 JWT 信息,如果合法,则允许用户的行为
因为 JWT 是自包含的(内部包含了一些会话信息),因此减少了需要查询数据库需要
因为用户的状态不再存储在服务端的内存中,所以这是一种无状态的认证机制
注意点
JWT 最大的优势是服务器不再需要存储 Session,使得服务器认证鉴权业务可以方便扩展。但这也是 JWT 最大的缺点:由于服务器不需要存储 Session 状态,因此使用过程中无法废弃某个 Token 或者更改 Token 的权限。也就是说一旦 JWT 签发了,到期之前就会始终有效,除非服务器部署额外的逻辑。
JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
JWT 适合一次性的命令认证,颁发一个有效期极短的 JWT,即使暴露了危险也很小,由于每次操作都会生成新的 JWT,因此也没必要保存 JWT,真正实现无状态。
JWT 和 session 的区别
Session
会话状态:Session是有状态的,需要在服务器上存储会话数据。JWT是无状态的,认证信息包含在Token中,并由客户端保存。
跨域认证:JWT更适合用于微服务架构和分布式系统中的跨域认证,因为它不依赖于单一的服务器来保存会话信息。
性能考量:使用Session可能会随着用户数量的增加而增加服务器的存储压力。而JWT则将存储负担转移到了客户端,减轻了服务器的压力。
安全策略:两种技术都需要采取措施保护用户会话不被劫持。对于Session,需要保护Session ID的安全;对于JWT,需要确保Token的安全传输和存储。
JWT
存储位置:JWT是一个包含了认证信息的JSON对象,经过签名后安全地在客户端和服务器间传输。JWT可以存储在客户端的LocalStorage或SessionStorage中,并在每次请求时通过HTTP头部发送给服务器。
安全性:JWT自身包含验证信息,因此无需在服务器上保存会话状态,这减少了服务器被攻击的风险。但是,如果JWT被截获,攻击者也可能冒充用户,因此安全地传输和存储JWT非常重要。
可扩展性:JWT更适用于分布式系统。由于不需要在服务器上存储会话信息,它支持无状态和跨域认证,这使得扩展应用程序变得更容易。