Spring Boot 项目单点登录(SSO)实现与最佳实践
一、背景与目标
在现代 Web 系统中,单点登录(SSO, Single Sign-On)是提升用户体验和安全性的关键能力。本文以实际 Spring Boot+前后端分离项目为例,介绍如何实现基于 Cookie+Token 的 SSO,支持 PC、移动端、WebView 等多端无缝集成。
二、方案原理
- Token 生成与存储:用户登录成功后,后端生成唯一 Token(如 UUID),写入数据库
user_token表,并通过Set-Cookie下发到前端。 - Cookie 自动携带:前端所有请求都加
withCredentials: true,浏览器自动带上auth_token,无需前端手动管理。 - Token 校验与续期:后端拦截器统一校验 Token,自动续期,保证活跃用户不会被踢下线。
- 单点登录:同一账号同一时间只有一个有效 Token,新登录会踢掉旧会话。
三、数据库表结构
1 | CREATE TABLE IF NOT EXISTS `user_token` ( |
- 每次登录生成新 Token,写入该表,保证单点登录。
- 过期时间支持 Token 续期。
四、关键后端实现
1. Token 生成与下发
1 | UserToken token = userTokenService.generateToken(loginUser.getId(), 30); |
2. Token 拦截器与续期机制
1 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { |
3. CORS 配置
1 | registry.addMapping("/**") |
五、前端对接要点与常见坑
- 全局设置
axios.defaults.withCredentials = true; - 所有请求都要加
withCredentials: true,否则不会自动带上auth_token。 - CORS 响应头
Access-Control-Allow-Origin必须是具体前端地址,不能是*。 - 登录后用 F12 检查 Cookie,确认
auth_token已保存。 - 多端/多标签页/iframe 天然支持 SSO。
- 常见坑:
- CORS 配置为
*时,浏览器不会带 Cookie,后端永远判定未登录。 - 代理配置不对,导致请求未转发到后端。
- Cookie 路径、域名设置不一致。
- CORS 配置为
六、生产环境安全建议
- Cookie 建议加
Secure属性,仅 HTTPS 下传输。 - 设置
SameSite=Lax或SameSite=Strict,防止 CSRF 攻击。 - Token 建议用高强度 UUID 或 JWT,防止伪造。
- Token 过期后自动登出,防止长期失效。
- 后端接口敏感操作需二次校验(如密码修改、资金操作等)。
七、接口文档引用
详见项目内doc/用户接口-前后端对接文档.md,包含登录、登出、Token 续期、系统管理员检测等接口说明。
八、常见异常案例与排查
- 接口返回 401 未登录:
- 检查 CORS 响应头,是否为具体前端地址。
- 检查请求是否带
auth_token。 - 检查 Token 是否已过期或被顶下线。
- 接口返回乱码或
?????????:- 检查拦截器是否拦截了无需登录的接口。
- 检查响应编码是否为 UTF-8。
- Token 未续期:
- 检查拦截器是否有自动续期逻辑。
九、最佳实践建议
- 后端 Token 拦截器统一校验,接口 Controller 无需关心登录态细节。
- CORS 配置必须严格,不能用
*,要用具体前端地址。 - Token 存储建议用数据库,便于单点登录和会话管理。
- 前端只需全局加
withCredentials: true,无需手动存取 Token。 - 退出登录时,后端删除 Token 并清除 Cookie。
- 支持 Token 自动续期,提升用户体验。
- 系统管理员相关接口应放行,无需登录即可初始化。
十、总结
基于 Cookie+Token 的 SSO 方案,兼顾了安全性、易用性和多端无缝集成。只要后端 CORS 和 Token 机制配置正确,前端开发几乎“零感知”,极大提升了系统的可维护性和用户体验。
如有更多 SSO、权限、跨域等实战问题,欢迎留言交流!