一、存在的意义是什么?
HTTP是无状态的简单来说就是每次请求服务器都不知道彼此之间是否有关系。
HTTP服务器在默认情况下无法直接判断连续的请求是否来自同一个用户。
所以需要一个工具来确定各个请求之间的关系,也就是session、cookie和token这些工具,它们之间的区别又是什么?
二、三者的区别
1. Cookie
定义与作用:
Cookie是由服务器发送到客户端浏览器并保存在本地的一小块数据。它主要用于跟踪用户会话、存储用户偏好设置、记住用户登录状态等。
特点:
-
存储在客户端浏览器中。
-
容量有限,单个Cookie的大小一般不超过4KB。
-
可以设置过期时间,过期后自动删除。
-
存在安全风险,因为存储在客户端,容易被用户查看、修改或窃取。
流程:
-
用户首次访问页面发送一个请求后,服务器生成一个唯一标识
-
服务器设置cookie的属性
-
服务器通过HTTP响应头中的
Set-Cookie
字段将这个标识符和其他Cookie信息发送给客户端(浏览器) -
浏览器会以键值对方式保存cookie信息
-
后续浏览器发送请求都会在请求头携带cookie信息,服务器会解析cookie信息识别用户
-
识别成功会根据会话状态提供对应的服务,执行用户操作
生命周期:
-
Cookie的生命周期由其过期时间决定。如果设置了过期时间,则Cookie在过期时间到达时会自动失效;如果没有设置过期时间,则Cookie默认为会话Cookie,在浏览器关闭时失效。
-
开发者可以通过设置
Max-Age
或Expires
属性来延长Cookie的生命周期。
2. Session
定义与作用:
Session是服务器端用来存储用户信息的一种机制。当用户访问网站时,服务器会为该用户创建一个唯一的Session,并生成一个Session ID。这个Session ID用于在多个请求之间保持用户的会话状态。
特点:
-
存储在服务器端,可以是内存、数据库或文件系统中。
-
可以存储大量数据,没有容量限制。
-
安全性较高,因为数据不存储在客户端。
-
存在性能影响,因为需要占用服务器资源。
流程:
-
客户端(浏览器)发送HTTP请求
-
服务器(tomcat)接收请求,并且为发起请求的这个用户创建一个唯一的session对象(session id是唯一标识)
-
服务器响应(发送session id给客户端),session id会被保存在一个名为JSESSIONID的cookie中,并通过HTTP响应的Set-Cookie头部发送给客户端。客户端(浏览器)会保存这个cookie,以便在后续的请求中携带
生命周期 :
- session可以设置过期时间
- 可以手动创建或销毁session
Session与Cookie的关系
-
Session机制通常与Cookie机制配合使用。Cookie用于在客户端存储Session ID,而Session则用于在服务器端存储用户的状态信息。
-
需要注意的是,虽然Session ID通常通过Cookie来传递,但Session本身并不依赖于Cookie。如果客户端禁用了Cookie,Session还可以通过URL重写或隐藏表单字段等方式来传递Session ID。
3. JWT
特点:
-
无状态,服务端不保存Token信息,只进行验证。
-
支持跨域,可以在不同的域名下使用。
-
安全性高,通常使用加密算法生成,不易被篡改和窃取。
-
适用于分布式系统,可以减轻服务器压力。
流程:
图片来源 什么是JWT?深入理解JWT从原理到应用(上)-阿里云开发者社区 (aliyun.com)
-
客户端(浏览器)发起请求,后端服务器生成一个jwt令牌,并返回给客户端(存储在请求头)
-
客户端在下一次时请求会携带jwt,后端服务器接收到请求并获取请求头,并且解析
生命周期:
1. 令牌创建
-
签发:当用户通过身份验证(如登录)后,服务器会生成一个JWT。这个JWT包含了用户的身份信息、权限、有效期等必要的数据,并通过服务器的私钥进行签名以确保其完整性和真实性。
-
传输:生成的JWT令牌会被发送给客户端(如浏览器或移动应用),通常是通过HTTP响应的头部(如Authorization)或作为请求体的一部分发送给客户端。
2. 令牌验证
-
携带:客户端在后续的请求中会携带这个JWT令牌,以便服务器验证用户的身份和权限。JWT令牌通常被放置在HTTP请求的头部(如
Authorization: Bearer <token>
)中。 -
校验:服务器在接收到请求后,会首先验证JWT令牌的有效性。这包括验证令牌的签名是否正确(使用服务器的公钥进行验证),以及令牌中的有效期是否已过(通过检查
exp
字段)。
3. 令牌使用
-
授权:一旦JWT令牌被验证为有效,服务器就会根据令牌中包含的信息(如用户身份和权限)来授权访问相应的资源或服务。
-
无状态:由于JWT是自包含的,服务器不需要在内存中或数据库中存储用户的会话状态。这使得JWT特别适用于分布式系统或微服务架构,因为它们可以轻松地在不同的服务之间共享JWT令牌进行身份验证和授权。
4. 令牌过期
-
自动过期:JWT令牌包含了一个
exp
(过期时间)字段,用于指定令牌的有效期。一旦令牌过期,它将不再被服务器接受,用户需要重新进行身份验证以获取新的JWT令牌。 -
令牌刷新:为了避免用户频繁重新登录,一些应用实现了JWT令牌的刷新机制。用户可以在令牌过期前使用刷新令牌(Refresh Token)来获取一个新的JWT令牌,而无需重新输入凭据。
总结:
特性 | Cookie | Session | JWT |
存储位置 | 客户端(浏览器) | 服务器端 | 客户端(通常存储在浏览器的localStorage、sessionStorage或cookie中) |
数据类型 | 主要为字符串(可序列化复杂对象) | 任意数据类型 | JSON格式,包含Header、Payload和Signature |
大小限制 | 一般不超过4KB(不同浏览器可能有所不同) | 无明显限制,但受服务器内存和配置影响 | 取决于编码后的长度,但通常较小 |
生命周期 | 可设置过期时间,默认为浏览器关闭时失效 | 可设置过期时间,用户长时间无活动或达到最大存活时间后失效 | 令牌中包含过期时间,过期后需重新获取 |
安全性 | 相对较低,数据保存在客户端,易被查看和修改 | 相对较高,数据保存在服务器端,用户无法直接访问 | 安全性较高,通过数字签名确保完整性和验证来源 |
无状态性 | 无状态(但依赖于客户端存储) | 无状态(服务器端通过Session ID管理状态) | 完全无状态,所有信息都包含在令牌中 |
性能影响 | 少量数据传输,对性能影响较小 | 依赖于服务器资源,大量Session可能增加服务器负担 | 减少服务器负担,因为无需存储会话状态 |
适用场景 | 存储少量的、非敏感的用户信息,如用户偏好设置 | 存储大量的、敏感的用户信息,如登录状态、购物车数据等 | 适用于分布式系统、微服务架构、API授权等场景 |
跨域性 | 依赖于浏览器cookie的跨域策略 | 通常限于单个应用域内 | JWT本身不限制跨域,但跨域使用需考虑CORS(跨源资源共享)策略 |
依赖 | 依赖于客户端的cookie支持 | 不依赖于客户端的特定存储机制,但通常通过cookie传递Session ID | 不依赖于任何特定的客户端存储机制,但可以选择存储位置 |