Cookie与Session简介-笔记
1.会话跟踪技术
1.1 什么叫“会话”
用户打开浏览器,访问某网站,期间点击了多个超链接,访问了多个web资源,然后关闭浏览器,上述整个过程称之为一个会话。
1.2 会话跟踪技术
会话跟踪(Session Tracking)是Web开发中用于识别和维护用户与服务器之间交互状态的技术。
- 由于HTTP协议本身是无状态的(即每次请求都是独立的),服务器无法直接知道用户是否已经登录、用户的历史操作等信息。
- 会话跟踪技术通过某种方式在多个请求之间保持用户的状态,从而实现个性化服务(如购物车、登录状态、用户偏好等)。
会话跟踪的核心目标:
- 标识用户身份:在多次请求中唯一识别用户。
- 保存用户状态:存储用户的临时数据(如登录信息、购物车内容)。
- 跨请求共享数据:允许服务器在不同页面或接口调用中访问用户相关的数据。
常见的会话跟踪技术
1. Cookie
- 原理:
- 服务器通过
Set-Cookie
响应头向浏览器发送数据,浏览器将 Cookie 存储在本地。 - 后续请求中,浏览器会自动将 Cookie 添加到请求头(
Cookie
字段)中发送给服务器。
- 服务器通过
- 特点:
- 客户端存储(大小限制:通常4KB)。
- 可设置过期时间(
Expires
或Max-Age
)。 - 可加密(如使用
HttpOnly
、Secure
标志增强安全性)。
- 适用场景:
- 轻量级状态存储(如用户偏好设置)。
- 配合 Session ID 使用(见下文)。
- 缺点:
- 受同源策略限制,跨域场景需处理 CORS。
- 存在 XSS 攻击风险(若未设置
HttpOnly
)。
2. Session(服务器端会话)
- 原理:
- 服务器为每个用户生成唯一的 Session ID(通常通过 Cookie 传输)。
- 服务器在内存或数据库中存储 Session 数据(如用户登录状态、临时数据)。
- 特点:
- 服务器端存储(无大小限制)。
- 更安全(数据不暴露给客户端)。
- Session ID 通常通过 Cookie 或 URL 重写传递。
- 适用场景:
- 需要高安全性或大量数据存储的场景(如用户登录状态)。
- 缺点:
- 依赖 Cookie(若禁用 Cookie,需用 URL 重写)。
- 分布式系统中需共享 Session(如使用 Redis 缓存)。
2. Cookie介绍
Cookie 是 Web 开发中的关键技术之一,用于在客户端(通常是浏览器)存储小型数据片段。它的核心目的是让服务器能够跟踪用户状态,从而实现个性化服务或维持会话。
2.1. Cookie 的核心功能
功能 | 说明 | 应用场景 |
---|---|---|
会话管理 | 保存用户登录状态或会话标识(如 session_id ) | 用户登录后保持登录状态 |
个性化设置 | 存储用户偏好(如语言、主题、地区) | 自动切换语言或界面样式 |
跟踪用户行为 | 记录访问历史、购物车内容或广告偏好 | 推荐商品或定向广告 |
数据缓存 | 减少服务器重复计算 | 缓存用户配置或临时数据 |
2.2. Cookie 的工作原理
- 服务器生成并发送 Cookie:通过 HTTP 响应头
Set-Cookie
发送给浏览器。 - 浏览器存储 Cookie:根据域名、路径、过期时间等规则保存。
- 浏览器自动携带 Cookie:后续请求相同域名时,通过 HTTP 请求头
Cookie
自动附加。
2.3. Cookie 的关键属性
属性 | 说明 |
---|---|
Name=Value | 键值对存储数据,如 user=abc123 |
Domain | 指定 Cookie 有效的域名(如 .example.com ) |
Path | 指定 Cookie 有效的路径(如 /api ) |
Expires/Max-Age | 设置过期时间(如 Max-Age=3600 表示 1 小时后过期) |
HttpOnly | 防止 JavaScript 访问(防范 XSS 攻击) |
Secure | 仅通过 HTTPS 传输(增强安全性) |
SameSite | 防止跨站请求伪造(CSRF),可设为 Strict /Lax /None |
2.4. Cookie 的使用示例
场景:用户登录后,服务器会将User信息放到Cookie里,后续通过 Cookie中的user校验身份。
-
step1:服务器生成含有
user信息的
Cookie,并发送给浏览器 -
step2: 浏览器存储 Cookie; 并在后续访问服务器时,自动携带Cookie信息
-
step3: 服务器从访问请求里获取Cookie信息,拿到
user
,验证用户身份。
package com.example.demo;import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@RestController
public class AuthController {//首次登陆时,服务端将 user名称放到cookie里传递给客户端@GetMapping("/login")public ResponseEntity<String> login(HttpServletResponse response) {// 服务端创建并设置 CookieCookie sessionCookie = new Cookie("user", "abc123");//会话标识sessionCookie.setMaxAge(3600); // 1小时后过期sessionCookie.setHttpOnly(true); //HttpOnly 和 Secure:确保 Cookie 仅通过 HTTPS 传输且无法被 JavaScript 读取sessionCookie.setSecure(true); // 仅通过 HTTPS 传输sessionCookie.setPath("/"); // 保证所有路径下可用response.addCookie(sessionCookie);return ResponseEntity.ok("Login successful");}//正常业务访问时,服务端会从请求里获取 Cookie来验证身份@GetMapping("/dashboard")public ResponseEntity<String> dashboard(HttpServletRequest request) {// 浏览器发起的请求中会携带 Cookie; // 服务端获取请求中的 CookieCookie[] cookies = request.getCookies();//服务端通过 session_id 查找用户会话,验证身份。String user = null;if (cookies != null) {for (Cookie cookie : cookies) {if ("user".equals(cookie.getName())) {user = cookie.getValue();break;}}}if ("abc123".equals(user)) {return ResponseEntity.ok("Welcome to the dashboard!");} else {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");}}
}
2.5 Cookie的
使用注意事项
- 安全性:避免在 Cookie 中存储敏感信息(如密码),使用加密或 Token 替代。
- 隐私合规:遵守 GDPR 等法规,明确告知用户 Cookie 的使用目的。
- 性能影响:减少 Cookie 大小和数量,避免影响请求速度。
2.6 Request里的Cookie与Response里的Set-Cookie
在浏览器里,我们可以看到 Request 和 Response的Header里都有Cookie信息:
- Response Header里有Set-Cookie
- Request Header里有 Cookie
Cookie
和 Set-Cookie
是 互为因果、相互配合 的机制:
-
初始化阶段:
- 用户首次访问服务器,请求中没有
Cookie
。 - 服务器响应中包含
Set-Cookie
,将一些信息(如 session ID)写入客户端。
- 用户首次访问服务器,请求中没有
-
后续请求阶段:
- 浏览器保存了这些 Cookie,并在之后的请求中通过
Cookie
头自动发送给服务器。 - 服务器通过读取
Cookie
中的信息,识别用户身份或状态。
- 浏览器保存了这些 Cookie,并在之后的请求中通过
-
更新阶段:
- 服务器可以再次通过
Set-Cookie
更新或添加新的 Cookie。
- 服务器可以再次通过
Cookie
和 Set-Cookie
对比:
特性 | Cookie (请求头) | Set-Cookie (响应头) |
---|---|---|
作用方向 | 客户端 → 服务器 | 服务器 → 客户端 |
作用 | 由浏览器发送,用于在请求中携带之前设置的 Cookie 数据,供服务器使用 | 由服务器发送,用于设置或更新客户端的 Cookie |
使用时机 | 浏览器在请求中自动携带之前服务器设置的 Cookie | 服务器在响应中设置新的 Cookie |
数据格式 | 多个键值对,用分号分隔(例如:key1=value1; key2=value2 ) | 每个 Cookie 一行,可带属性(例如:key=value; Path=/; HttpOnly ) |
数量 | 一个请求中只能有一个 Cookie 头 | 一个响应中可以有多个 Set-Cookie 头 |
通过这种Cookie
机制,HTTP 协议虽然本身是无状态的,却能够实现类似有状态的交互体验,如用户登录、购物车记录、个性化设置等。
3.Session介绍
Session(会话) 是服务器端用于跟踪用户状态的一种机制。由于 HTTP 协议本身是 无状态 的(即每次请求都是独立的,服务器无法直接识别用户身份),Session 通过为每个用户分配一个唯一的标识(Session ID),在服务器端存储用户相关的数据,从而实现用户状态的持久化跟踪。
3.1 Session的核心功能
-
用户身份识别
用户登录后,服务器生成一个唯一的 Session ID,并将其返回给客户端(通常通过 Cookie)。后续请求中,客户端携带该 ID,服务器即可识别用户身份。 -
数据存储与共享
服务器为每个 Session ID 维护一个数据存储空间(如内存、数据库或文件),用于保存用户相关的临时数据(如用户信息、购物车内容等)。 -
会话生命周期管理
Session 有明确的生命周期:- 创建:用户首次访问时生成。
- 更新:用户持续交互时自动刷新过期时间。
- 销毁:用户主动退出或超时未活动后清除。
-
安全性
Session 数据存储在服务器端,客户端仅保存 Session ID,因此比 Cookie 更安全(敏感数据不暴露给客户端)。
3.2 Session 的工作流程
- 用户首次访问服务器,服务器生成唯一的 Session ID。
- 服务器将 Session ID 通过 Cookie 返回给客户端。
- 客户端后续请求中自动携带该 Cookie(含 Session ID)。
- 服务器根据 Session ID 查找对应的会话数据,完成状态跟踪。
3.4 Session的典型应用场景
- 用户登录与认证
登录后将用户 ID 存入 Session,后续请求无需重复验证。 - 购物车功能
在 Session 中临时存储用户添加的商品信息。 - 个性化设置
保存用户的主题偏好、语言选择等临时配置。
3.5 Session的使用示例
场景:用户首次访问服务器,服务器生成唯一的 session_id,并通过Cookie传递给客户端,后续通过浏览器自动携带的Cookie中的session_id来校验身份。
package com.example.demo;import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@RestController
public class SessionController {//首次登陆时,服务端将 session_id 放到cookie里传递给客户端@GetMapping("/login")public ResponseEntity<String> login(HttpServletResponse response) {// 服务端创建并设置 CookieCookie sessionCookie = new Cookie("session_id", "abc123");//会话标识sessionCookie.setMaxAge(3600); // 1小时后过期sessionCookie.setHttpOnly(true); //HttpOnly 和 Secure:确保 Cookie 仅通过 HTTPS 传输且无法被 JavaScript 读取sessionCookie.setSecure(true); // 仅通过 HTTPS 传输sessionCookie.setPath("/"); // 保证所有路径下可用response.addCookie(sessionCookie);return ResponseEntity.ok("Login successful");}//正常业务访问时,服务端会从请求里获取 Cookie中的session_id来验证身份@GetMapping("/dashboard")public ResponseEntity<String> dashboard(HttpServletRequest request) {// 浏览器发起的请求中会携带 Cookie; // 服务端获取请求中的 CookieCookie[] cookies = request.getCookies();//服务端通过 session_id 查找用户会话,验证身份。String sessionId = null;if (cookies != null) {for (Cookie cookie : cookies) {if ("session_id".equals(cookie.getName())) {sessionId = cookie.getValue();break;}}}if ("abc123".equals(sessionId)) {return ResponseEntity.ok("Welcome to the dashboard!");} else {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");}}
}
3.6 Session的使用注意事项
1. Session ID 安全性
- 避免 Session ID 泄露(如通过 HTTPS 传输)。
- 使用强随机算法生成 Session ID。
2. 存储方式
- 默认可能存储在服务器文件系统,高并发场景建议使用 Redis 或数据库。
3. 超时设置
- 合理配置 Session 超时时间(如 30 分钟无操作后过期)。
4. 客户端 Cookie 管理
- 如果客户端禁用 Cookie,需通过 URL 重写传递 Session ID(如
?PHPSESSID=xxx
)。
4. Cookie与Session的对比
4.1. 功能对比
概念 | 功能 |
---|---|
Cookie | 客户端存储机制,用于在浏览器中存储小型数据片段,每次 HTTP 请求自动发送到服务器。 |
Session | 服务器端存储机制,用于在服务器上维护用户状态,通常依赖 Cookie 传递 Session ID 来识别用户。 |
4.2. 主要区别
特性 | Cookie | Session |
---|---|---|
存储位置 | 客户端(浏览器) | 服务器端(内存、数据库等) |
安全性 | 较低(暴露给客户端,易受 XSS 攻击) | 较高(敏感数据存储在服务器) |
数据类型 | 仅支持字符串 | 支持任意 Java 对象(通过序列化) |
存储容量 | 单个 Cookie 通常限制为 4KB,单个域名最多 20 个 Cookie | 无明确限制(受服务器资源限制) |
生命周期 | 可自定义过期时间(默认浏览器关闭后失效) | 默认在用户关闭浏览器或超时后失效(可通过配置调整) |
依赖关系 | 独立使用 | 通常依赖 Cookie 存储 Session ID |
4.3. 二者联系
- Session 依赖 Cookie
默认情况下,Session 的实现依赖 Cookie 存储 Session ID(如JSESSIONID
)。浏览器通过 Cookie 自动将 Session ID 发送给服务器,服务器据此识别用户会话。 - 协同工作
通常两者结合使用:Cookie 保存 Session ID,Session 保存实际数据。若客户端禁用 Cookie,则需通过 URL 重写(如;jsessionid=xxx
)传递 Session ID。
4.4 适用场景
场景 | 推荐机制 |
---|---|
用户登录状态保持 | Session(敏感信息存储在服务器) |
个性化设置(如主题偏好) | Cookie(客户端存储,减少服务器负载) |
购物车临时数据 | Session(避免数据丢失) |
跨域共享数据 | Cookie(配合跨域策略) |