OAuth2 单点登录流程图

OAuth2 单点登录流程图

基于授权码模式的 SSO 实现方案


一、首次登录流程(用户访问应用A,未登录)

用户浏览器 应用A app-a.com 认证中心 auth.com 后端服务 访问应用A首页 1 检测无Token 2 302重定向到认证中心 3 跳转认证中心 /authorize?client_id=app-a &redirect_uri=app-a.com/callback &response_type=code&state=xxx 4 检测无登录Cookie 5 返回登录页面 6 提交账号密码 7 验证用户身份 8 验证通过 9 设置登录Cookie (auth.com域下) 10 生成授权码code 11 302重定向 app-a.com/callback?code=xxx 12 携带code回调 13 POST /oauth/token code=xxx&client_secret=yyy 14 返回 access_token + refresh_token 15 登录成功,返回Token 16 存储Token到localStorage 17 用户浏览器 应用A app-a.com 认证中心 auth.com 后端服务


二、静默登录流程(用户访问应用B,已登录过认证中心)

用户浏览器 应用B app-b.com 认证中心 auth.com 访问应用B首页 1 检测无Token 2 302重定向到认证中心 3 跳转认证中心 /authorize?client_id=app-b&... 🔑 浏览器自动携带auth.com的Cookie 4 ✅ 检测到登录Cookie 用户已登录,无需输密码 5 直接生成授权码code 6 302重定向 app-b.com/callback?code=yyy 7 携带code回调 8 POST /oauth/token code=yyy&client_secret=zzz 9 返回 access_token + refresh_token 10 登录成功(用户无感知) 11 🎉 单点登录完成!用户无需再次输入密码 用户浏览器 应用B app-b.com 认证中心 auth.com


三、Token刷新流程

用户浏览器 应用 认证中心 请求业务接口 Header: Bearer access_token 1 验证Token 2 401 Token已过期 3 POST /oauth/token grant_type=refresh_token refresh_token=xxx 4 返回新的 access_token + refresh_token 5 更新本地Token 6 用新Token重试原请求 7 返回业务数据 8 401 需要重新登录 9 清除本地Token 10 跳转登录页 11 alt refresh_token有效 refresh_token也过期 用户浏览器 应用 认证中心


四、单点登出流程

用户浏览器 应用A 认证中心 应用B 点击登出按钮 1 POST /oauth/logout token=xxx 2 清除登录Cookie 3 使Token失效 4 回调通知登出 POST /logout-callback 5 清除本地会话 6 opt 通知其他应用(可选) 登出成功 7 清除本地Token 8 跳转到登录页 9 所有应用都已登出 用户浏览器 应用A 认证中心 应用B


五、完整架构图

后端服务 认证中心 前端应用 用户端 1. 访问 1. 访问 1. 访问 2. 未登录跳转 2. 未登录跳转 2. 未登录跳转 3. 登录成功 4. 已登录检测 5. 发放code 5. 发放code 5. 发放code 6. code换token 6. code换token 6. code换token 7. 携带token请求 7. 携带token请求 7. 携带token请求 业务API Token验证 登录页面 认证接口 登录Cookie
auth.com域 应用A
app-a.com 应用B
app-b.com 应用C
app-c.com 用户浏览器


六、核心要点

6.1 为什么能"单点"?

应用跳转 认证中心域 auth.com 自动携带Cookie 自动携带Cookie 自动携带Cookie 检测已登录 应用A跳转来 应用B跳转来 应用C跳转来 登录Cookie
session=abc123 直接发code
无需再输密码

6.2 各角色职责

角色 职责
认证中心 登录页面、验证用户、发放code/token、维护Cookie
各应用前端 检测Token、跳转认证中心、存储Token
后端服务 用code换token、验证token

6.3 安全措施

环节 措施 防护目标
state参数 随机值校验 CSRF攻击
client_secret 后端保存,换token时使用 code劫持
redirect_uri 预注册白名单 钓鱼攻击
PKCE code_verifier/challenge 授权码拦截

七、Token存储方案

flowchart TB subgraph 双Token机制 AT[Access Token<br/>有效期:15分钟] RT[Refresh Token<br/>有效期:7天] end subgraph 存储位置 AT -->|存储| LS[localStorage<br/>XSS可读但影响小] RT -->|存储| Cookie[HttpOnly Cookie<br/>XSS读不到] end subgraph 使用方式 LS -->|Header携带| API[请求API] Cookie -->|自动携带| Refresh[刷新Token] end

八、时序总结

步骤 首次登录 二次登录(已登录)
1 访问应用 访问应用
2 跳转认证中心 跳转认证中心
3 显示登录页 跳过(检测到Cookie)
4 输入账号密码 跳过
5 设置Cookie + 生成code 直接生成code
6 重定向回应用 重定向回应用
7 code换token code换token
8 登录成功 登录成功(无感知)

相关推荐
风流 少年16 分钟前
Spring AI 2.0:Flux
java·人工智能·spring
m0_5474866620 分钟前
《面向对象与Java程序设计》全套PPT课件2026
java·开发语言
jason成都32 分钟前
ignav-next|Java 层封装 GNSS/INS 组合导航框架,隔离 RTKLIB 与 INS 内核,双模块独立演进、最小侵入
java·开发语言
抓不住时间的沙32 分钟前
butterfly主题美化,打造属于自己的个性博客
java·开发语言·前端·javascript·node.js·github
Zane199443 分钟前
从一个发短信的类到多态调用:封装、继承、多态到底是怎么长出来的
java·后端
MarkHD1 小时前
Stable Diffusion入门第19-20天:保存与分享你的工作流——第一阶段收官,从“能用”到“可复用”
java·开发语言·stable diffusion
爱敲键盘的猴子1 小时前
Spring MVC 详解(一):全注解开发与请求响应处理
java·spring·mvc
counting money1 小时前
SpringBoot 项目创建(IDEA不全,还需要修改)
java·spring boot·spring·maven
Dr.kangder1 小时前
嵌入式面试总结(二十二)——指针
java·面试·职场和发展·架构·嵌入式
阿部多瑞 ABU1 小时前
从0到1:用 Spring Boot 3.4 + Vue3 做一个能“智能排道次“的运动会编排系统(附核心算法)
java·spring boot·后端·算法·spring