前后端验证方式

第一部分:核心概念详解

一、基础概念

1. 认证(Authentication)
  • 定义:验证"你是谁",确认身份
  • 例子:登录时验证用户名密码
  • 类比:出示身份证证明身份
2. 授权(Authorization)
  • 定义:验证"你能做什么",确认权限
  • 例子:登录后检查是否有权限访问某个功能
  • 类比:有会员卡,但不同等级权限不同
3. Cookie(小饼干)
  • 定义:服务器发给浏览器的一小段文本,浏览器保存并在后续请求中自动发送
  • 特点:
  • 存储在浏览器(客户端)
  • 每次请求自动发送
  • 有大小限制(通常4KB)
  • 可设置过期时间
  • 可设置作用域(域名/路径)
  • 格式示例: Set-Cookie: auth_session=abc123; Path=/; HttpOnly; Expires=Wed, 21 Oct 2025 07:28:00 GMT
  • 组成部分:
  • 名称和值:auth_session=abc123
  • 路径:Path=/(哪些路径可用)
  • 过期时间:Expires=...(何时失效)
  • 安全标志:
  • HttpOnly:只能通过HTTP访问,JavaScript不能读取
  • Secure:只能通过HTTPS传输
4. Session(会话)
  • 定义:服务器端存储的用户会话信息,用SessionID标识
  • 特点:
  • 存储在服务器(内存或Redis/数据库)
  • 每个用户有唯一SessionID
  • SessionID通常通过Cookie传递
  • 服务器可根据SessionID查找会话数据
  • 存储内容示例: SessionID: sess_abc123

    存储数据: {

    userId: "123",

    username: "zhangsan",

    loginTime: "2024-01-01 10:00:00"

    }

5. SessionID(会话标识符)
  • 定义:Session的唯一标识符
  • 特点:
  • 通常是一串随机字符串
  • 通过Cookie传递给客户端
  • 服务器用SessionID查找对应的Session
  • 示例:sess_abc123def456
6. Token(令牌)
  • 定义:用于身份验证的凭证
  • 特点:
  • 可以是任意格式的字符串
  • 包含身份信息或指向身份信息的标识
  • 有有效期
  • 常见类型:
  • 随机字符串Token(如:abc123def456)
  • JWT Token(结构化Token)
  • API Key(简单密钥)
7. JWT(JSON Web Token)
  • 定义:标准化的Token格式,包含用户信息,经过签名,可自验证
  • 结构(三部分,用.分隔): Header.Payload.Signature
  • 三部分详解:
  • Header(头部):说明类型和签名算法 {

    "alg": "HS256", // 签名算法

    "typ": "JWT" // Token类型

    }

  • Payload(载荷):存放用户信息 {

    "userId": "123",

    "username": "zhangsan",

    "exp": 1234567890, // 过期时间

    "iat": 1234567800 // 签发时间

    }

  • Signature(签名):用密钥对Header和Payload进行签名 HMACSHA256(

    base64UrlEncode(header) + "." + base64UrlEncode(payload),

    secret

    )

8. 签名(Signature)
  • 定义:用密钥对内容进行加密计算的结果,用于防篡改
  • 作用:
  • 证明Token由你的服务器签发
  • 防止Token被篡改
  • 工作原理:
  • 生成时:用密钥对内容计算签名
  • 验证时:用同样的密钥重新计算签名,对比是否一致
9. 密钥(Secret Key)
  • 定义:用于生成和验证签名的关键字符串,必须保密
  • 特点:
  • 只有服务器知道
  • 如果泄露,攻击者可以伪造Token
  • 必须足够复杂和安全
10. Base64编码
  • 定义:将二进制数据转换为可打印字符的编码方式
  • 作用:JWT中用于编码Header和Payload
  • 特点:
  • 不是加密,只是编码
  • 可以轻松解码
  • 用于传输,不用于安全
11. HMAC-SHA256
  • 定义:一种加密算法,用于生成签名
  • 工作原理:
  • 输入:内容和密钥
  • 输出:固定长度的签名
  • 特点:相同输入产生相同输出,不同输入产生不同输出
12. 过期时间(Expiration Time)
  • 定义:Token或Session的有效期限
  • 作用:
  • 限制Token的使用时间
  • 提高安全性(即使Token泄露,也会过期)
  • 常见设置:
  • 短期Token:1小时、24小时
  • 长期Token:7天、30天
13. 黑名单(Blacklist)
  • 定义:已失效但未过期的Token列表
  • 作用:
  • 实现Token注销功能
  • 即使Token未过期,也可以使其失效
  • 存储方式:通常存储在Redis中
14. 有状态(Stateful)
  • 定义:服务器需要存储会话信息
  • 特点:
  • 服务器需要存储Session
  • 需要查询数据库或缓存
  • 扩展性较差(多服务器需要共享Session)
  • 例子:Session认证
15. 无状态(Stateless)
  • 定义:服务器不需要存储会话信息
  • 特点:
  • 服务器不需要存储
  • 所有信息都在Token中
  • 扩展性好(任何服务器都可以验证)
  • 例子:JWT认证

二、认证方式概念

1. Session认证
  • 定义:使用Session存储用户信息的认证方式
  • 特点:有状态、服务器存储、可主动注销
  • 流程:登录→创建Session→返回SessionID→后续请求验证Session
2. JWT认证
  • 定义:使用JWT Token的认证方式
  • 特点:无状态、客户端存储、无法主动注销
  • 流程:登录→生成JWT→返回Token→后续请求验证Token
3. OAuth 2.0
  • 定义:第三方授权标准
  • 特点:标准化、支持第三方登录、流程复杂
  • 流程:用户授权→获取授权码→换取Token→访问资源
4. API Key认证
  • 定义:使用简单密钥的认证方式
  • 特点:简单、性能好、安全性较低
  • 流程:生成Key→请求携带Key→验证Key

第二部分:完整内容讲解

一、认证的本质和目的

1. 认证的目的
  • 确认用户身份:验证"你是谁"
  • 建立信任关系:登录后给凭证
  • 保护资源:只有已登录用户才能访问
  • 追踪用户:记录谁在做什么操作
2. 认证的两个阶段
  • 阶段1:登录(建立信任)
  • 用户提交凭证(用户名密码)
  • 服务器验证凭证
  • 服务器生成Token
  • 返回Token给客户端
  • 阶段2:验证(确认信任)
  • 用户携带Token
  • 服务器验证Token
  • 确认是已登录用户
  • 允许访问资源

二、Session认证详解

1. 工作原理

用户登录

服务器验证用户名密码

服务器创建Session,存储用户信息

服务器生成SessionID

服务器通过Cookie返回SessionID

浏览器保存Cookie

后续请求自动携带Cookie

服务器根据SessionID查找Session

从Session中获取用户信息

允许访问

2. 详细流程
  • 登录时:
  1. 用户提交用户名密码
  1. 服务器验证
  1. 创建Session,存储用户信息
  1. 生成SessionID(如:sess_abc123)
  1. 通过Set-Cookie返回SessionID
  1. 浏览器保存Cookie
  • 后续请求时:
  1. 浏览器自动在请求头携带Cookie
  1. 服务器提取SessionID
  1. 根据SessionID查找Session
  1. 从Session中获取用户信息
  1. 验证通过,允许访问
3. 优点
  • 可主动注销:删除Session即可
  • 安全性好:敏感信息在服务器
  • 可存储较多信息:Session可以存储任意数据
4. 缺点
  • 需要服务器存储:增加服务器负担
  • 扩展性差:多服务器需要共享Session
  • 性能开销:每次请求需要查询Session
5. 适用场景
  • 传统Web应用
  • 单体应用
  • 需要频繁注销的场景

三、JWT认证详解

1. JWT的结构

完整Token = Header.Payload.Signature

例如:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjMiLCJ1c2VybmFtZSI6InpoYW5nc2FuIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

2. JWT的生成过程
  • 步骤1:准备内容
  • Header:{"alg":"HS256","typ":"JWT"}
  • Payload:{"userId":"123","username":"zhangsan"}
  • 步骤2:Base64编码
  • 编码Header和Payload
  • 步骤3:拼接
  • 待签名内容 = Header + "." + Payload
  • 步骤4:用密钥签名
  • Signature = HMAC-SHA256(待签名内容, 密钥)
  • 步骤5:Base64编码签名
  • 编码Signature
  • 步骤6:组合
  • 完整Token = Header + "." + Payload + "." + Signature
3. JWT的验证过程
  • 步骤1:拆分Token
  • 提取Header、Payload、Signature
  • 步骤2:重新计算签名
  • 用同样的密钥重新计算签名
  • 步骤3:对比签名
  • 如果新签名 == Token中的Signature → 验证通过
  • 如果新签名 != Token中的Signature → 验证失败
  • 步骤4:检查过期时间
  • 从Payload中提取exp字段
  • 如果当前时间 > exp → Token已过期
  • 步骤5:提取用户信息
  • 从Payload中提取用户信息(userId、username等)
4. 为什么签名能保证安全
  • 只有拥有密钥的服务器才能生成正确签名
  • 如果内容被改,重新计算的签名会不同
  • 如果签名被改,验证会失败
  • 攻击者不知道密钥,无法伪造签名
5. 优点
  • 无状态:服务器不需要存储
  • 跨域友好:可以跨域使用
  • 可携带用户信息:Payload中可以存储用户信息
  • 适合微服务:任何服务器都可以验证
6. 缺点
  • 无法主动注销:需要黑名单机制
  • Token较大:比SessionID大很多
  • 泄露风险:如果Token泄露,在过期前都可以使用
7. 适用场景
  • 微服务架构
  • 移动端应用
  • 跨域场景
  • 需要无状态认证的场景

四、Cookie和Session的关系

1. 关系说明
  • Cookie是传递SessionID的载体
  • Session是服务器端的会话存储
  • SessionID是Session的唯一标识符
  • 通常用Cookie传递SessionID
2. 工作流程

用户登录

服务器创建Session(存储用户信息)

服务器生成SessionID

服务器通过Cookie返回SessionID

Set-Cookie: JSESSIONID=sess_abc123

浏览器保存Cookie

后续请求自动携带Cookie

Cookie: JSESSIONID=sess_abc123

服务器根据SessionID查找Session

从Session中获取用户信息

3. 类比
  • Cookie = 会员卡(上面有会员号)
  • Session = 会员档案(存在店里的系统里)
  • SessionID = 会员号(写在会员卡上)

五、项目中的混合认证机制

1. 为什么需要混合机制
  • 跨服务认证:wflow服务需要调用table服务
  • table服务不直接信任wflow服务
  • 需要一种跨服务的认证方式
2. 完整流程
  • 第一步:生成JWT Token
  • wflow服务获取用户信息
  • 将用户信息放入JWT的Payload
  • 用密钥签名生成Token
  • 第二步:用JWT Token换取Session Cookie
  • wflow构造URL:/api/auth/user-token/{jwtToken}
  • 向table服务发送GET请求
  • table服务验证Token签名
  • table服务解析Payload获取用户信息
  • table服务创建Session,存储用户信息
  • table服务生成SessionID
  • table服务通过Set-Cookie返回auth_session=xxx
  • wflow从响应头提取Cookie
  • 第三步:使用Session Cookie进行后续请求
  • wflow在后续请求的Cookie头中带上auth_session=xxx
  • table服务根据SessionID查找Session
  • table服务从Session中获取用户信息
  • 验证通过,处理业务请求
3. 为什么这样设计
  • 跨服务信任:JWT作为临时凭证,table服务可以验证用户身份
  • 性能优化:后续请求用Session,避免重复解析JWT
  • 可控性:table服务可以管理Session的生命周期

六、如何验证用户身份

1. JWT能验证什么
  • Token是否由你的服务器签发(签名验证)
  • Token是否被篡改(内容完整性)
  • Token是否过期(时间有效性)
2. JWT不能验证什么
  • 用户是否真的是你的用户(身份真实性)
  • 用户是否还有权限(权限有效性)
  • 用户是否被禁用(账户状态)
3. 完整的用户验证流程
  • 步骤1:验证Token本身(JWT验证)
  • 验证Token格式
  • 验证签名
  • 验证是否过期
  • 从Payload中提取userId
  • 步骤2:验证用户身份(数据库验证)
  • 用提取的userId查询数据库
  • 检查用户是否存在
  • 检查用户状态(是否被禁用、是否被删除)
  • 检查用户权限
  • 步骤3:验证会话状态(可选)
  • 检查Token是否在黑名单中
  • 检查用户的登录状态
  • 检查用户最近是否修改了密码

七、认证方式对比

认证方式 存储位置 状态 主要优点 主要缺点 典型场景
Session 服务器 有状态 可主动注销、安全性好 需要存储、扩展性差 传统Web应用
JWT 客户端 无状态 无状态、跨域友好 无法主动注销、Token较大 微服务、移动端
OAuth 2.0 授权服务器 混合 标准化、支持第三方 复杂度高 第三方登录
API Key 客户端 无状态 简单、性能好 安全性较低 服务间调用

八、关键要点总结

1. 认证的本质
  • 登录 = 建立信任关系
  • 验证 = 确认信任关系
  • Token = 身份凭证
2. 核心概念
  • Cookie:浏览器存储的小文本
  • Session:服务器端的会话存储
  • SessionID:Session的唯一标识符
  • Token:身份验证的凭证
  • JWT:标准化的Token格式
  • 签名:防篡改的机制
3. 验证流程
  • 每次请求都要验证Token
  • 确保请求来自已登录用户
  • 防止未授权访问
  • 可以检查用户状态
4. 安全要点
  • 密钥必须保密
  • Token有有效期
  • 使用HTTPS传输
  • 定期更新Token

为什么要把 Token 和 Session 做比较?

一、核心原因

1. 它们解决同一个问题,但方式不同
  • 问题:如何验证用户身份
  • Session:服务器存储用户信息,用 SessionID 标识
  • Token:客户端携带用户信息,用签名保证安全
  • 结论:需要比较以选择合适方案
2. 它们有本质区别
  • Session:有状态(服务器存储)
  • Token:无状态(客户端存储)
  • 结论:理解区别有助于正确使用
3. 项目使用了混合机制
  • 项目同时使用了 JWT Token 和 Session Cookie
  • 需要理解两者如何配合
  • 结论:比较有助于理解混合机制

二、Token 和 Session 的本质区别

1. 存储位置不同

Session:

用户信息存储在哪里?

→ 服务器端(内存/Redis/数据库)

客户端存储什么?

→ 只存储SessionID(一个标识符)

类比:

→ 银行存钱,你只拿存折(SessionID),钱在银行(Session)

Token(JWT):

用户信息存储在哪里?

→ 客户端(Token的Payload中)

服务器存储什么?

→ 不存储,只存储密钥用于验证

类比:

→ 现金(Token),钱在你手里,不需要银行

2. 验证方式不同

Session:

验证流程:

  1. 客户端发送SessionID

  2. 服务器根据SessionID查找Session

  3. 从Session中获取用户信息

  4. 验证通过

需要查询数据库/缓存:

→ 每次请求都要查询Session

Token(JWT):

验证流程:

  1. 客户端发送Token

  2. 服务器验证Token签名

  3. 从Token的Payload中提取用户信息

  4. 验证通过

不需要查询数据库:

→ 只需要验证签名,不需要查询

3. 状态管理不同

Session(有状态):

服务器需要:

→ 存储每个用户的Session

→ 管理Session的生命周期

→ 处理Session的过期和清理

多服务器问题:

→ 需要共享Session(Redis/数据库)

→ 否则用户在不同服务器登录状态不一致

Token(无状态):

服务器不需要:

→ 不存储任何会话信息

→ 所有信息都在Token中

多服务器优势:

→ 任何服务器都可以验证Token

→ 不需要共享存储

→ 天然支持水平扩展


三、为什么需要比较它们?

1. 选择合适方案

场景1:传统Web应用(单体)

推荐:Session认证

原因:

  • 用户在同一服务器上

  • 需要频繁注销功能

  • 安全性要求高

场景2:微服务架构

推荐:JWT Token认证

原因:

  • 多个服务需要验证用户

  • 不需要共享Session存储

  • 性能要求高

场景3:移动端应用

推荐:JWT Token认证

原因:

  • 无状态,适合移动端

  • 不需要维护Session

  • 跨域友好

2. 理解混合使用

项目中的混合机制:

为什么用JWT Token?

→ 跨服务认证(wflow服务调用table服务)

为什么用Session Cookie?

→ 性能优化(避免重复解析JWT)

如何配合?

→ JWT Token换取Session Cookie

→ 后续请求用Session Cookie

3. 避免常见误区

误区1:认为Token就是Session

错误理解:

→ Token和Session是一样的

正确理解:

→ Token是凭证,Session是存储

→ 它们可以配合使用,但不是同一个东西

误区2:认为有Token就不需要Session

错误理解:

→ 用了Token就不需要Session了

正确理解:

→ 可以只用Token(纯JWT)

→ 也可以Token+Session(混合机制)

→ 根据场景选择

误区3:认为Session比Token安全

错误理解:

→ Session更安全,Token不安全

正确理解:

→ 都有安全风险

→ Session:需要保护SessionID不被盗用

→ Token:需要保护密钥不被泄露

→ 安全性取决于实现方式,不是机制本身


四、Token 和 Session 的关系

1. 它们不是对立的

不是:

→ Token vs Session(二选一)

而是:

→ 两种不同的认证机制

→ 可以单独使用

→ 也可以配合使用

2. 它们可以配合使用

项目中的实际应用:

第一步:生成JWT Token

→ wflow服务生成Token(包含用户信息)

第二步:用Token换取Session

→ table服务验证Token

→ table服务创建Session

→ table服务返回Session Cookie

第三步:使用Session

→ 后续请求用Session Cookie

→ 避免重复解析JWT

3. 它们各有优势

Session的优势:

✅ 可以主动注销

✅ 服务器完全控制

✅ 可以存储大量信息

✅ 安全性好(敏感信息在服务器)

Token的优势:

✅ 无状态,扩展性好

✅ 跨域友好

✅ 性能好(不需要查询)

✅ 适合微服务


五、为什么项目要混合使用?

1. 跨服务认证需求

问题:

→ wflow服务需要调用table服务

→ table服务不直接信任wflow服务

解决:

→ 用JWT Token作为跨服务的凭证

→ table服务可以验证Token,确认用户身份

2. 性能优化

问题:

→ 如果每次请求都解析JWT,性能开销大

解决:

→ 第一次用JWT Token换取Session

→ 后续请求用Session Cookie

→ 避免重复解析JWT

3. 可控性

问题:

→ JWT Token无法主动注销

解决:

→ 用Session管理会话

→ 可以主动注销Session

→ 可以管理Session的生命周期


六、总结:为什么需要比较

1. 理解本质区别
  • Session = 服务器存储 + SessionID标识
  • Token = 客户端存储 + 签名验证
  • 理解区别才能正确使用
2. 选择合适的方案
  • 不同场景适合不同方案
  • 比较有助于选择
  • 也可以混合使用
3. 理解项目设计
  • 项目使用了混合机制
  • 需要理解两者如何配合
  • 理解设计意图
4. 避免常见误区
  • 它们不是对立的
  • 它们可以配合使用
  • 各有优势和适用场景

七、通俗总结

类比说明:

Session认证:

就像去银行存钱:

  • 你把钱存在银行(Session存储在服务器)

  • 你拿存折(SessionID)

  • 每次取钱都要去银行(查询Session)

  • 银行可以冻结你的账户(主动注销)

Token认证:

就像用现金:

  • 钱在你手里(Token在客户端)

  • 不需要银行(不需要服务器存储)

  • 直接使用(验证签名即可)

  • 但丢了就没了(无法主动注销)

混合机制:

就像先用现金换会员卡:

  • 第一次:用现金(JWT Token)换会员卡(Session Cookie)

  • 后续:用会员卡(Session Cookie)消费

  • 既解决了跨服务问题,又优化了性能


八、关键要点

  1. Token 和 Session 不是对立的
  • 它们是不同的认证机制
  • 可以单独使用,也可以配合使用
  1. 比较的目的是理解区别
  • 存储位置不同
  • 验证方式不同
  • 适用场景不同
  1. 项目混合使用的原因
  • 跨服务认证(JWT Token)
  • 性能优化(Session Cookie)
  • 可控性(Session管理)
  1. 选择合适的方案
  • 根据场景选择
  • 可以单独使用
  • 也可以混合使用

这就是为什么要把 Token 和 Session 做比较的原因。它们解决同一个问题,但方式不同,理解它们的区别和关系,有助于正确使用和选择合适的方案。

一、什么叫"有状态"?

1. 有状态(Stateful)的定义

有状态 = 服务器需要记住/存储信息

生活比喻:

有状态就像:

  • 你去银行存钱,银行要记录你的账户信息

  • 你去餐厅办会员卡,餐厅要记录你的会员信息

  • 你去医院看病,医院要记录你的病历

关键:服务器需要"记住"每个用户的信息

2. Session 为什么是有状态的?

用户A登录

服务器创建Session,存储:

{

sessionId: "sess_abc123",

用户信息: {

userId: "123",

username: "zhangsan",

loginTime: "2024-01-01 10:00:00"

}

}

服务器需要"记住"这个Session

存储在:内存/Redis/数据库

这就是"有状态"

关键点:

  • 服务器需要存储每个用户的Session
  • 需要管理Session的生命周期
  • 需要查询数据库/缓存来获取Session信息

3. 无状态(Stateless)的定义

无状态 = 服务器不需要记住/存储信息

生活比喻:

无状态就像:

  • 你用现金买东西,商店不需要记住你是谁

  • 你出示身份证,警察验证后就不需要记住你

  • 你出示会员卡,店员验证后就不需要记住你

关键:服务器不需要"记住"任何信息

4. JWT Token 为什么是无状态的?

用户A登录

服务器生成JWT Token:

{

Header: {...},

Payload: {

userId: "123",

username: "zhangsan"

},

Signature: "..."

}

服务器返回Token给客户端

服务器不需要存储任何信息

后续请求:

客户端发送Token

服务器验证Token签名(不需要查询数据库)

从Token中提取用户信息

这就是"无状态"

关键点:

  • 服务器不需要存储任何会话信息
  • 所有信息都在Token中
  • 验证时只需要验证签名,不需要查询

5. 对比总结

特性 有状态(Session) 无状态(JWT Token)
服务器存储 需要存储Session 不需要存储
查询数据库 每次请求都要查询 不需要查询
扩展性 多服务器需要共享Session 任何服务器都可以验证
性能 需要查询,性能较差 不需要查询,性能好
可控性 可以主动注销 无法主动注销

二、SessionID 被乱猜怎么办?

1. 问题的本质

你的担心:

如果攻击者乱猜一个SessionID,比如:

sess_abc123

如果这个SessionID确实存在怎么办?

攻击者是不是就可以冒充这个用户了?

2. SessionID 的安全性设计

设计1:SessionID 是随机生成的

SessionID不是简单的数字:

❌ 不是:sess_1, sess_2, sess_3(容易被猜中)

✅ 而是:sess_a8f3b2c1d9e4f5g6h7i8j9k0(随机字符串)

特点:

  • SessionID是随机生成的
  • 长度足够长(通常32-128字符)
  • 包含字母、数字、特殊字符
  • 几乎不可能被猜中
设计2:SessionID 的生成方式

常见的生成方式:

  1. UUID(通用唯一标识符)

→ 例如:550e8400-e29b-41d4-a716-446655440000

→ 可能性:2^122 种组合(几乎不可能重复)

  1. 随机字符串

→ 例如:a8f3b2c1d9e4f5g6h7i8j9k0l1m2n3o4p5

→ 长度:32-128字符

→ 可能性:天文数字

  1. 加密算法生成

→ 使用加密算法生成随机字符串

→ 更加安全

设计3:SessionID 的验证机制

即使攻击者猜中了一个SessionID,还有多层保护:

保护1:Session 有过期时间

Session不是永久存在的:

  • 通常设置过期时间(如:30分钟、1小时)

  • 过期后Session自动失效

  • 即使猜中,也可能已经过期

保护2:Session 可以绑定IP地址

服务器可以记录:

  • SessionID: sess_abc123

  • 绑定的IP: 192.168.1.100

如果攻击者用不同的IP访问:

  • 服务器检测到IP不匹配

  • 拒绝访问,要求重新登录

保护3:Session 可以绑定User-Agent

服务器可以记录:

  • SessionID: sess_abc123

  • 绑定的User-Agent: Mozilla/5.0...

如果攻击者用不同的浏览器访问:

  • 服务器检测到User-Agent不匹配

  • 拒绝访问,要求重新登录

保护4:Session 可以记录最后访问时间

服务器可以检测:

  • SessionID: sess_abc123

  • 最后访问时间: 2024-01-01 10:00:00

  • 当前时间: 2024-01-01 15:00:00

如果时间间隔异常:

  • 服务器可以要求重新验证

  • 或者直接使Session失效

3. 实际攻击场景分析

场景1:暴力猜测SessionID

攻击者尝试:

sess_1, sess_2, sess_3, ..., sess_1000000

问题:

  1. SessionID是随机字符串,不是连续数字

  2. 即使尝试100万次,猜中的概率也几乎为0

  3. 服务器可以检测异常请求,封禁IP

场景2:SessionID 泄露

如果SessionID真的泄露了(比如被截获):

  1. 攻击者可以使用这个SessionID

  2. 但Session有过期时间

  3. 服务器可以检测异常行为,主动使Session失效

  4. 用户重新登录,旧Session失效

场景3:Session 固定攻击

攻击者诱导用户使用他提供的SessionID:

  1. 攻击者生成一个SessionID

  2. 诱导用户使用这个SessionID登录

  3. 攻击者就可以使用这个SessionID

防护:

  • 每次登录都生成新的SessionID

  • 不信任用户提供的SessionID

4. 最佳实践

实践1:使用HTTPS

HTTPS加密传输:

  • SessionID在传输过程中被加密

  • 攻击者无法截获SessionID

实践2:设置HttpOnly标志

Set-Cookie: JSESSIONID=sess_abc123; HttpOnly

作用:

  • JavaScript无法读取Cookie

  • 防止XSS攻击窃取SessionID

实践3:设置Secure标志

Set-Cookie: JSESSIONID=sess_abc123; Secure

作用:

  • 只能通过HTTPS传输

  • 防止在HTTP中被截获

实践4:定期更换SessionID

每次重要操作后:

  • 生成新的SessionID

  • 使旧SessionID失效

  • 防止SessionID被长期使用


三、混合场景详解

1. 混合场景是什么?

混合场景 = JWT Token + Session Cookie 配合使用

不是只用JWT Token

也不是只用Session

而是:先用JWT Token,再换成Session Cookie

2. 为什么需要混合场景?

问题1:跨服务认证

场景:

  • wflow服务需要调用table服务

  • table服务不直接信任wflow服务

  • 需要一种跨服务的认证方式

解决:

  • wflow服务生成JWT Token(证明用户身份)

  • table服务验证JWT Token(确认用户身份)

问题2:性能优化

如果只用JWT Token:

  • 每次请求都要解析JWT

  • 解析JWT需要计算签名

  • 性能开销大

如果只用Session:

  • 第一次请求需要创建Session

  • 但无法跨服务使用

混合方案:

  • 第一次:用JWT Token换取Session Cookie

  • 后续:用Session Cookie(性能好)

3. 混合场景的完整流程

第一步:生成JWT Token

wflow服务:

  1. 获取用户信息(userId, username, email)

  2. 生成JWT Token

{

Header: {...},

Payload: {

userId: "123",

username: "zhangsan",

email: "zhangsan@example.com"

},

Signature: "..."

}

  1. Token包含用户身份信息

wflow服务 → table服务:

  1. 构造URL:/api/auth/user-token/{jwtToken}

  2. 发送GET请求,URL中携带Token

table服务收到请求:

  1. 从URL中提取JWT Token

  2. 验证Token签名(确认Token有效)

  3. 从Token的Payload中提取用户信息

  4. 创建Session,存储用户信息

{

sessionId: "sess_abc123",

用户信息: {

userId: "123",

username: "zhangsan",

email: "zhangsan@example.com"

}

}

  1. 生成SessionID:sess_abc123

  2. 通过Set-Cookie返回Session Cookie

Set-Cookie: auth_session=sess_abc123

wflow服务:

  1. 从响应头中提取Cookie

  2. 得到:auth_session=sess_abc123

第三步:使用Session Cookie进行后续请求

wflow服务 → table服务:

  1. 在请求头中携带Cookie

Cookie: auth_session=sess_abc123

table服务收到请求:

  1. 从Cookie中提取SessionID

  2. 根据SessionID查找Session

  3. 从Session中获取用户信息

  4. 验证通过,处理业务请求

4. 混合场景的优势

优势1:解决跨服务认证

问题:

  • wflow服务和table服务是独立的

  • table服务不直接信任wflow服务

解决:

  • JWT Token作为跨服务的凭证

  • table服务可以验证Token,确认用户身份

优势2:性能优化

如果只用JWT Token:

  • 每次请求都要解析JWT

  • 解析需要计算签名,性能开销大

混合方案:

  • 第一次:解析JWT(一次开销)

  • 后续:使用Session(查询缓存,性能好)

优势3:可控性

如果只用JWT Token:

  • 无法主动注销

  • Token在过期前一直有效

混合方案:

  • 可以主动注销Session

  • 可以管理Session的生命周期

5. 混合场景的流程图

┌─────────────────────────────────────────────────────────┐

│ 步骤1:生成JWT Token │

│ wflow服务生成Token(包含用户信息) │

└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐

│ 步骤2:用Token换取Session Cookie │

│ wflow → table: GET /api/auth/user-token/{token} │

│ table验证Token → 创建Session → 返回Cookie │

└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐

│ 步骤3:使用Session Cookie │

│ wflow → table: 请求 + Cookie: auth_session=xxx │

│ table查找Session → 获取用户信息 → 处理请求 │

└─────────────────────────────────────────────────────────┘

6. 为什么不能只用一种?

只用JWT Token的问题

问题1:性能开销

  • 每次请求都要解析JWT

  • 解析需要计算签名,性能开销大

问题2:无法主动注销

  • Token在过期前一直有效

  • 即使知道Token泄露,也无法立即失效

只用Session的问题

问题1:跨服务认证

  • Session无法跨服务使用

  • table服务无法验证wflow服务的Session

问题2:扩展性

  • 多服务器需要共享Session

  • 需要Redis/数据库存储

混合方案的优势

优势1:解决跨服务认证

  • JWT Token可以跨服务使用

优势2:性能优化

  • 后续请求用Session,性能好

优势3:可控性

  • 可以主动注销Session

总结

1. 有状态 vs 无状态

  • 有状态 = 服务器需要存储信息(Session)
  • 无状态 = 服务器不需要存储信息(JWT Token)

2. SessionID 安全性

  • SessionID是随机生成的,几乎不可能被猜中
  • 即使猜中,也有多层保护(过期时间、IP绑定等)
  • 使用HTTPS、HttpOnly、Secure等安全措施

3. 混合场景

  • 先用JWT Token(跨服务认证)
  • 再换成Session Cookie(性能优化)
  • 结合两者优势,解决实际问题
相关推荐
万行5 天前
机器人系统ROS2
人工智能·python·机器学习·机器人·计算机组成原理
myloveasuka7 天前
[计算机组成原理]总线判优控制
计算机组成原理
渡我白衣8 天前
计算机组成原理(15):定点数的移位运算
人工智能·神经网络·机器学习·硬件架构·硬件工程·计算机组成原理·移位运算
sulikey9 天前
计算机组成原理第二章: 数据的机器级表示与处理 - 个人期末复习资料
计算机组成原理·期末考试
万行11 天前
机器学习&第一章
人工智能·python·机器学习·flask·计算机组成原理
551只玄猫13 天前
数电实验3【译码器设计实验报告】数字电路 逻辑与计算机设计 logisim
数字电路·计算机组成原理·数电·实验报告·译码器·logisim
渡我白衣15 天前
计算机组成原理(13):多路选择器与三态门
开发语言·javascript·ecmascript·数字电路·计算机组成原理·三态门·多路选择器
大模型铲屎官21 天前
【操作系统-Day 46】文件系统核心探秘:深入理解连续分配与链式分配的实现与优劣
人工智能·python·深度学习·大模型·操作系统·文件系统·计算机组成原理
大模型铲屎官21 天前
【操作系统-Day 47】揭秘Linux文件系统基石:图解索引分配(inode)与多级索引
linux·运维·服务器·人工智能·python·操作系统·计算机组成原理