一、Web会话机制概览
Web会话机制用于追踪和识别用户的连续操作,常见于登录、购物车、权限管理等场景。主流方案有:
- Cookie
- URL重写
- 隐藏表单域
- HttpSession
- 分布式Session(如Spring Session/Redis)
- Token机制(JWT、OAuth2、OpenID Connect)
- 前后端分离的Token+API网关
- SSO(单点登录,CAS、SAML、OIDC)
二、主流会话机制技术栈、场景与细化剖析
1. Cookie
典型场景
- 轻量级用户标识
- 记住登录状态、首选项、广告跟踪
具体方法
- Java:
Cookie
类的addCookie()
、getCookies()
- Node.js:
res.cookie()
、req.cookies
- Python Flask:
make_response
、request.cookies
内部逻辑
- 服务器生成Cookie,通过响应头
Set-Cookie
下发给浏览器 - 浏览器存储并在后续请求自动携带
- 服务器读取Cookie识别身份
源码片段(Java Servlet)
// 写Cookie
Cookie cookie = new Cookie("userId", "10086");
cookie.setMaxAge(3600); // 1小时
response.addCookie(cookie);
// 读Cookie
for (Cookie c : request.getCookies()) {
if ("userId".equals(c.getName())) {
String userId = c.getValue();
}
}
流程图
[服务端] --(Set-Cookie)--> [浏览器]
[浏览器] --(带Cookie访问)--> [服务端]
速记口诀
服务端发,浏览器存,自动携带,身份确认。
2. URL重写
典型场景
- Cookie禁用情况下的会话追踪
具体方法
- Java Servlet:
response.encodeURL("/home.jsp")
内部逻辑
- 检查浏览器是否支持Cookie
- 不支持时,SessionID拼接到URL参数
- 服务器解析URL参数恢复会话
源码片段
String url = response.encodeURL("/home.jsp");
response.sendRedirect(url); // URL自动带jsessionid参数
流程图
[服务端] --(url?jsessionid=xxxx)--> [浏览器]
[浏览器] --(带jsessionid访问)--> [服务端]
速记口诀
禁Cookie,拼参数,URL带ID,识会话。
3. 隐藏表单域
典型场景
- 多步表单流程、Cookie禁用场景
具体方法
- HTML:
<input type="hidden" name="sessionId" value="xxxx"/>
内部逻辑
- SessionID嵌入表单隐藏域
- 表单提交时带上SessionID
- 服务器解析参数识别会话
源码片段
<form method="post" action="/next">
<input type="hidden" name="sessionId" value="${sessionId}"/>
</form>
流程图
[服务端] --(表单隐藏sessionId)--> [浏览器]
[浏览器] --(表单提交带sessionId)--> [服务端]
速记口诀
隐藏域,表单传,识会话,防丢失。
4. HttpSession(J2EE/Servlet原生)
典型场景
- 单体应用的用户登录、购物车、权限管理
具体方法
request.getSession()
session.setAttribute()/getAttribute()
session.invalidate()
内部逻辑
- 服务器为每个用户分配Session对象
- SessionID存于Cookie或URL
- Session数据服务端存储,客户端只持有SessionID
源码片段
HttpSession session = request.getSession();
session.setAttribute("username", "Tom");
String user = (String) session.getAttribute("username");
session.invalidate(); // 登出
流程图
[浏览器] --(首次访问)--> [服务端] (创建Session,返回SessionID)
[浏览器] --(带SessionID访问)--> [服务端] (查找Session)
速记口诀
一人一会,ID识别,服务端管,失效销毁。
5. 分布式Session(Spring Session/Redis)
典型场景
- 多节点集群,负载均衡
- 微服务统一会话
具体方法
- Spring配置
spring.session.store-type=redis
- 应用代码与普通Session一致
内部逻辑
- Spring拦截Session操作,存储到Redis等外部中间件
- 各节点共享Session数据
源码片段
spring:
session:
store-type: redis
redis:
host: 127.0.0.1
port: 6379
流程图
[应用A] <--> [Redis] <--> [应用B]
(所有节点访问同一Redis存Session)
速记口诀
Spring接管,Redis存,共享会话,横向扩。
6. Token机制(JWT、OAuth2、OIDC)
典型场景
- 前后端分离
- 移动端、微服务API
- 第三方登录/SSO
具体方法
- JWT库生成/校验Token
- Token放Header或本地存储
- 后端解码JWT或校验Access Token
JWT生成与校验(Java)
// 生成JWT
String token = Jwts.builder()
.setSubject("user1")
.signWith(SignatureAlgorithm.HS256, "myKey")
.compact();
// 校验JWT
Claims claims = Jwts.parser()
.setSigningKey("myKey")
.parseClaimsJws(token)
.getBody();
OAuth2/OIDC流程
- 客户端重定向到授权服务器
- 用户授权后回调带授权码
- 用授权码换Access Token和ID Token
- 前端携带Token访问API
流程图(JWT)
[登录] --(获取JWT)--> [客户端]
[客户端] --(带JWT访问)--> [服务端] (验签解码)
流程图(OAuth2/OIDC)
[客户端] --(授权)--> [授权服务器] --(Token)--> [客户端]
[客户端] --(Token)--> [业务API]
速记口诀
Token签发,前端存,携带访问,无状态验。
7. SSO(单点登录,CAS/SAML/OIDC)
典型场景
- 企业多系统统一登录
- 教育、政务、金融等多门户统一认证
具体方法
- CAS:基于Ticket Granting Ticket
- SAML:基于XML的断言
- OIDC:OAuth2基础上加ID Token
OIDC集成(Spring Security)
spring:
security:
oauth2:
client:
registration:
google:
client-id: xxx
client-secret: xxx
scope: openid, profile, email
provider:
google:
issuer-uri: https://accounts.google.com
@GetMapping("/user")
public Map<String, Object> user(@AuthenticationPrincipal OidcUser principal) {
return principal.getClaims();
}
流程图
[子系统A] --(重定向认证)--> [SSO服务器] --(登录成功)--> [子系统B]
(无需重复登录,SSO统一认证)
速记口诀
一点登录,票据通,认证发令,系统通行。
三、速查表
技术点 | 典型场景 | 关键API/方法 | 速记口诀 |
---|---|---|---|
Cookie | 记住登录、小数据 | addCookie/getCookies | 服务端发,浏览器存,自动携带,身份确认 |
URL重写 | Cookie禁用 | encodeURL | 禁Cookie,拼参数,URL带ID,识会话 |
隐藏表单域 | 多步表单、禁Cookie | input hidden | 隐藏域,表单传,识会话,防丢失 |
HttpSession | 单体应用 | getSession/setAttribute | 一人一会,ID识别,服务端管,销毁失效 |
分布式Session | 集群、微服务 | Spring Session/Redis | Spring接管,Redis存,共享会话,横向扩 |
JWT | 前后端分离、微服务 | Jwts.builder/parser | Token签发,前端存,携带访问,无状态验 |
OAuth2/OIDC | SSO、第三方登录 | /authorize,/token | 授权认证,令牌带,身份验,资源取 |
SSO | 企业门户 | CAS/SAML/OIDC | 一点登录,票据通,认证发令,系统通行 |
四、详细注释与口诀示例
Cookie注释
// 创建一个名为userId的Cookie,有效期1小时
Cookie cookie = new Cookie("userId", "10086"); // 用户唯一标识
cookie.setMaxAge(3600); // 有效期3600秒
response.addCookie(cookie); // 添加到响应头
// 遍历请求中的所有Cookie,找到userId
for (Cookie c : request.getCookies()) {
if ("userId".equals(c.getName())) {
String userId = c.getValue(); // 获取用户ID
}
}
口诀:服务端发,浏览器存,自动携带,身份确认。
JWT注释
// 生成JWT,包含用户信息,使用密钥签名
String token = Jwts.builder()
.setSubject("user1") // 用户名
.signWith(SignatureAlgorithm.HS256, "myKey") // 签名算法和密钥
.compact(); // 得到Token字符串
// 校验JWT,提取用户信息
Claims claims = Jwts.parser()
.setSigningKey("myKey") // 验证签名
.parseClaimsJws(token) // 解析
.getBody(); // 获取负载数据
口诀:Token签发,前端存,携带访问,无状态验。
五、流程图模板(ASCII版)
HttpSession流程
[浏览器] --(首次访问)--> [服务端] (分配Session, 返回SessionID)
[浏览器] --(带SessionID访问)--> [服务端] (查找/创建Session)
JWT流程
[客户端] --(登录)--> [服务端] (签发JWT)
[客户端] --(带JWT访问)--> [服务端] (验证签名,解码信息)
六、总结与建议
- 单体应用:优先用
HttpSession
,简单高效 - 分布式/微服务:推荐
分布式Session
或Token机制
(如JWT) - 前后端分离/移动端:优选
JWT
或OAuth2/OIDC
- 企业级SSO:落地
CAS/SAML/OIDC
口诀总汇
会话机制多,场景需分明,
Cookie轻量用,禁用拼URL,
单体Session快,集群用Redis,
分离用Token,认证靠OIDC。
如需某一机制源码深度剖析、全流程实战代码、特定场景最佳实践,请随时指定!