认证方案对比:Session 方式 vs Token 方式
Spring Security 与 Sa-Token 两种认证方案的全面对比
一、Session 方式(Spring Security)
依赖
spring-boot-starter-security
核心类
| 类名 | 说明 |
SecurityConfig | Spring Security 配置(禁用 CSRF、放行请求、配置 Session 持久化) |
WebConfig | 注册自定义拦截器 |
LoginCheckInterceptor | 拦截请求,校验登录状态 |
LoginServiceImpl | 登录时向 SecurityContextHolder 写入认证信息 |
SecurityUtil | 工具类,检查是否登录、获取当前用户 |
PermissionException | 自定义未登录异常 |
GlobalExceptionHandler | 全局异常处理,返回统一 JSON |
登录流程
- 用户
POST /login/by/account
LoginServiceImpl 创建 UsernamePasswordAuthenticationToken(account)
SecurityContextHolder.getContext().setAuthentication(auth)
- 请求结束,
SecurityContextHolderFilter 自动将认证信息保存到 HTTP Session
- 响应头
Set-Cookie: JSESSIONID=xxx
请求校验流程
- 请求携带
Cookie: JSESSIONID=xxx
SecurityContextHolderFilter 从 Session 恢复认证信息到 SecurityContextHolder
LoginCheckInterceptor 调用 SecurityUtil.isAuthenticated()
true → 放行,Controller 执行
false → 抛出 PermissionException → GlobalExceptionHandler 返回 Result.fail()
- 请求结束,SecurityContext 自动保存回 Session
获取当前用户
SecurityUtil.getCurrentUserId()
优点
- 浏览器自动携带 Cookie,前端无需额外处理
- Apifox 等测试工具默认支持 Cookie
- Spring 生态原生支持
缺点
- 配置复杂,涉及多个类
- 依赖服务端 Session,集群部署需额外配置 Session 共享(如 Redis Session)
- 扩展功能(踢人下线、权限校验等)需自行实现
二、Token 方式(Sa-Token)
依赖
sa-token-spring-boot3-starter
核心类
| 类名 | 说明 |
WebConfig | 注册 Sa-Token 路由拦截器(一行配置) |
LoginServiceImpl | 登录时调用 StpUtil.login(account) 生成 Token |
GlobalExceptionHandler | 捕获 NotLoginException,返回统一 JSON |
登录流程
- 用户
POST /login/by/account
LoginServiceImpl 调用 StpUtil.login(account)
- Sa-Token 生成 Token,存入缓存(内存/Redis),建立 Token → 用户 映射
- 响应返回 Token 字符串
请求校验流程
- 请求携带请求头
satoken: xxx(或 Cookie: satoken=xxx)
SaInterceptor 拦截器调用 StpUtil.checkLogin()
- 从请求头/Cookie 获取 Token
- 去缓存查 Token 对应的用户
- 查到 → 放行,Controller 执行
- 查不到/过期 → 抛出
NotLoginException → GlobalExceptionHandler 返回 Result.fail()
获取当前用户
StpUtil.getLoginId()
优点
- 极简配置,核心代码仅 3 行(
StpUtil.login / SaRouter.check / StpUtil.getLoginId)
- 无状态,天然支持集群/微服务(Token 存 Redis,任何节点都能验证)
- 内置丰富的扩展功能:踢人下线、权限校验、账号封禁、SSO 单点登录等
- 支持内存/Redis/自定义多种存储方式
缺点
- 前端需手动在请求头添加 Token(但可通过 axios 拦截器等自动处理)
- 测试工具(Apifox)需配置变量自动提取 Token
- 非 Spring 官方框架
三、核心差异总结
| 项目 | Session 方式 | Token 方式 |
| 登录凭证 | JSESSIONID Cookie | 自定义 Token 字符串 |
| 凭证存储位置 | 服务端 HTTP Session | 缓存(内存/Redis) |
| 凭证传递方式 | 浏览器自动带 Cookie | 请求头或 Cookie(需配置) |
| 集群部署 | 需额外配置 Session 共享 | 天然支持(集中存储) |
| 配置复杂度 | 5+ 个类 | 1 个拦截器配置类 |
| 扩展功能 | 需自行实现 | 框架内置(踢人、权限等) |
四、你的项目中两种方式的对应关系
| Spring Security | Sa-Token |
SecurityContextHolder | StpUtil 内部缓存 |
UsernamePasswordAuthentication | StpUtil.login() |
SecurityUtil.isAuthenticated() | StpUtil.isLogin() |
SecurityUtil.getCurrentUserId() | StpUtil.getLoginId() |
LoginCheckInterceptor | SaInterceptor + SaRouter |
PermissionException | NotLoginException |
SecurityConfig | (无需配置,引入依赖即用) |