# sa-token-parent **Repository Path**: haojianwei/sa-token-parent ## Basic Information - **Project Name**: sa-token-parent - **Description**: lingma生成的satoken demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-11 - **Last Updated**: 2026-05-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SA-Token SSO 单点登录演示项目 ## 项目说明 本项目演示了**不同域名、不同 Redis** 的多系统间如何实现 SSO 单点登录。 ### 架构 ``` ┌──────────────────────────────────────────────────────┐ │ SSO 登录中心 (port:9000) │ │ Redis db=0 (独立) │ │ - 统一认证 │ │ - 票据签发与校验 │ └────────────┬─────────────────────────┬───────────────┘ │ │ ┌────────▼────────┐ ┌────────▼────────┐ │ 系统A (port:9001) │ │ 系统B (port:9002) │ │ Redis db=1 (独立) │ │ Redis db=2 (独立) │ │ - 自有用户体系 │ │ - 自有用户体系 │ │ - 各自的 Sa-Token│ │ - 各自的 Sa-Token│ └──────────────────┘ └──────────────────┘ ``` ### SSO 流程 #### 方式一:浏览器重定向流程(适用于 Web 页面) 1. 用户访问 `http://localhost:9001/dashboard`(系统A) 2. 系统A 拦截器检测到未登录 → 重定向到 SSO 登录中心 3. 用户在 SSO 登录中心输入用户名密码登录 4. SSO 登录中心创建服务器会话,生成一次性票据(ticket) 5. 重定向回系统A 的回调地址,携带 ticket 6. 系统A 后端调用 SSO 服务器校验 ticket,获取用户信息 7. 系统A 在本地 Redis 中创建登录会话(`StpUtil.login()`),返回系统A页面 8. 用户点击"跳转到系统B" → 系统B 检测未登录 → 重定向到 SSO 登录中心 9. **SSO 登录中心已有会话** → 直接生成 ticket 跳转回系统B 10. 系统B 校验票短并在本地 Redis 创建会话 — **无需再次输入密码** #### 方式二:Token 交换流程(适用于 API / 移动端) 1. 调用 SSO 服务器登录接口获取 `serverToken` 2. 调用系统A 的 Token 交换接口 → 传入 `serverToken` → 获取 `localTokenA` 3. 调用系统B 的 Token 交换接口 → 传入 `serverToken` → 获取 `localTokenB` 4. 使用 `localTokenA` 调用系统A 的 API 5. 使用 `localTokenB` 调用系统B 的 API ## 技术栈 | 组件 | 版本 | |------|------| | JDK | 17 | | Spring Boot | 3.2.5 | | Sa-Token | 1.39.0 | | Redis | 任意版本 | ## 快速启动 ### 前置条件 1. JDK 17+ 2. Maven 3.8+ 3. 本地 Redis 服务运行中 ### 启动 SSO 登录中心 ```bash cd sso-server mvn spring-boot:run ``` 启动后访问:http://localhost:9000/api/sso/login ### 启动系统 A ```bash cd sso-client mvn spring-boot:run -Dspring-boot.run.profiles=client-a ``` 启动后访问:http://localhost:9001 ### 启动系统 B ```bash cd sso-client mvn spring-boot:run -Dspring-boot.run.profiles=client-b ``` 启动后访问:http://localhost:9002 ### 演示账号 | 用户名 | 密码 | 角色 | |--------|------|------| | admin | 123456 | 管理员 | | zhangsan | 123456 | 普通用户 | | lisi | 123456 | 普通用户 | ## API 接口 ### SSO 登录中心 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/sso/login?redirect=xxx` | 登录页面(浏览器) | | POST | `/api/sso/login` | 登录表单提交,form 参数:username, password | | GET | `/api/sso/validateTicket?ticket=xxx` | 校验票据(客户端后端调用)| | GET | `/api/sso/validateToken?token=xxx` | 校验 Server Token(客户端后端调用)| | GET | `/api/sso/logout?redirect=xxx` | 退出登录 | ### 客户端系统 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/sso/callback?ticket=xxx&redirect=xxx` | SSO 回调地址 | | POST | `/api/token/exchange?serverToken=xxx` | Token 交换(API 方式)| | GET | `/api/sso/me` | 获取当前用户信息 | | POST | `/api/sso/logout` | 退出当前系统 | ## Token 交换示例 ### 1. 登录获取 Server Token ```bash curl -X POST http://localhost:9000/api/sso/login \ -d "username=admin&password=123456" ``` ### 2. 在系统A 换取本地 Token ```bash curl -X POST http://localhost:9001/api/token/exchange \ -d "serverToken=xxxxxx" ``` ### 3. 在系统B 换取本地 Token ```bash curl -X POST http://localhost:9002/api/token/exchange \ -d "serverToken=xxxxxx" ``` ### 4. 使用本地 Token 访问系统 ```bash curl http://localhost:9001/dashboard \ -H "client-token: xxxxxx" ``` ## 扩展新系统 要新增一个系统C,只需: 1. 在 `sso-client/src/main/resources/` 下新增 `application-client-c.yml`: ```yaml server: port: 9003 spring: data: redis: database: 3 application: name: sso-client-c sso: client: id: sso-client-c name: 系统C callback-url: http://localhost:9003/api/sso/callback ``` 2. 使用 profile `client-c` 启动: ```bash mvn spring-boot:run -Dspring-boot.run.profiles=client-c ``` ## 核心设计要点 1. **独立 Redis**:每个客户端系统使用不同的 Redis db,会话完全隔离 2. **一次性票据**:Server 将用户信息编码为一次性票据(ticket),客户端凭票到中心换取用户信息 3. **Sa-Token 本地方案**:每个系统独立使用 `StpUtil.login()` 创建自己的会话 4. **Server Token**:登录中心签发的长生命周期 token,可在各客户端之间共享以换取本地 token