OAuth 2.0 单点登录已成功集成到标注平台!现在可以使用 SSO 认证中心进行登录。
backend/config.yaml)oauth:
enabled: true
base_url: "http://192.168.92.61:8000"
client_id: "sRyfcQwNVoFimigzuuZxhqd36fPkVN5G"
client_secret: "96RuKb4obAn9bQ9i5NtINiKBMvF_9uuCR7eNzD9dWQMbOWZaV3P593-8yLOqzWRd"
redirect_uri: "http://localhost:4200/auth/callback"
scope: "profile email"
http://192.168.92.61:8000/oauth/authorizehttp://192.168.92.61:8000/oauth/tokenhttp://192.168.92.61:8000/oauth/userinfo后端:
cd backend
python main.py
前端:
cd web
yarn nx serve lq_label
打开浏览器访问: http://localhost:4200/login
http://192.168.92.61:8000)http://localhost:4200/auth/callback)登录成功后,你应该能看到:
1. 用户点击"使用 SSO 登录"
↓
2. 前端调用 /api/oauth/login 获取授权 URL 和 state
↓
3. 前端保存 state 到 sessionStorage
↓
4. 前端重定向到 OAuth 授权页面
↓
5. 用户在 SSO 登录并授权
↓
6. OAuth 重定向回 /auth/callback?code=xxx&state=yyy
↓
7. 前端验证 state 参数
↓
8. 前端调用 /api/oauth/callback 用 code 换取 token
↓
9. 后端用 code 向 OAuth 换取 access_token
↓
10. 后端用 access_token 获取用户信息
↓
11. 后端同步用户到本地数据库
↓
12. 后端生成本地 JWT tokens
↓
13. 前端保存 tokens 和用户信息
↓
14. 前端跳转到首页
| 端点 | 方法 | 描述 |
|---|---|---|
/api/oauth/login |
GET | 获取授权 URL 和 state |
/api/oauth/callback |
GET | 处理 OAuth 回调,换取 token |
/api/oauth/status |
GET | 获取 OAuth 配置状态 |
获取授权 URL:
curl http://localhost:8000/api/oauth/login
响应:
{
"authorization_url": "http://192.168.92.61:8000/oauth/authorize?response_type=code&client_id=sRyfcQwNVoFimigzuuZxhqd36fPkVN5G&redirect_uri=http://localhost:4200/auth/callback&scope=profile+email&state=xxx",
"state": "xxx"
}
处理回调:
curl "http://localhost:8000/api/oauth/callback?code=xxx&state=yyy"
响应:
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "bearer",
"user": {
"id": "user_xxx",
"username": "testuser",
"email": "test@example.com",
"role": "annotator",
"created_at": "2024-01-22T..."
}
}
sub 或 id 字段)oauth_provider: "sso"oauth_id: OAuth 用户 IDusername: OAuth 用户名email: OAuth 邮箱role: "annotator"(默认)password_hash: ""(OAuth 用户不需要密码)oauth_provider 和 oauth_id 查找用户当前实现:
annotator(标注员)未来扩展:
admin 和 annotator 两种角色原因: OAuth 服务器上的应用 ID 配置不正确
解决方案:
backend/config.yaml 中的 client_id 是正确的sRyfcQwNVoFimigzuuZxhqd36fPkVN5G原因: 回调 URL 未在 OAuth 服务器上配置
解决方案:
http://localhost:4200/auth/callback原因: React StrictMode 在开发环境下会导致组件渲染两次,授权码被使用两次
解决方案:
oauth-callback.tsx 中添加防重复调用逻辑(使用 isProcessing 状态)症状: 配置文件中 client_id 和 client_secret 的值搞反了
正确配置:
oauth:
client_id: "sRyfcQwNVoFimigzuuZxhqd36fPkVN5G"
client_secret: "96RuKb4obAn9bQ9i5NtINiKBMvF_9uuCR7eNzD9dWQMbOWZaV3P593-8yLOqzWRd"
检查:
检查:
redirect_uri 配置正确检查:
原因: sessionStorage 被清除或浏览器不支持
解决方案:
请使用 SSO 认证中心提供的测试账号进行测试。
curl http://localhost:8000/api/oauth/status
cd backend
sqlite3 annotation_platform.db
SELECT * FROM users WHERE oauth_provider = 'sso';
cd backend
sqlite3 annotation_platform.db
DELETE FROM users WHERE oauth_provider = 'sso';
修改 backend/config.yaml:
oauth:
redirect_uri: "http://your-production-domain.com/auth/callback"
修改 backend/main.py:
app.add_middleware(
CORSMiddleware,
allow_origins=[
"http://your-production-domain.com",
],
...
)
OAuth 单点登录已成功集成!主要特性:
现在可以使用 SSO 登录标注平台了!🎉
实现日期: 2024-01-22
状态: ✅ 完成
文档版本: 1.0