mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-19 21:14:21 +08:00
feat(auth): 添加 SECTL Auth OAuth 登录功能
- 新增 OAuth 登录组件和回调页面 - 集成 Tauri 深度链接插件处理 OAuth 回调 - 添加账户设置页面显示登录信息 - 更新 CI 配置添加 OAuth 环境变量 - 扩展 API 接口支持 OAuth 相关操作 - 添加国际化支持
This commit is contained in:
@@ -0,0 +1,311 @@
|
||||
# OAuth 2.0 授权流程文档
|
||||
|
||||
本文档详细说明 SECTL Auth 的 OAuth 2.0 授权流程,帮助第三方应用开发者接入统一认证服务。
|
||||
|
||||
## 概述
|
||||
|
||||
SECTL Auth 实现了标准的 OAuth 2.0 授权码流程(Authorization Code Flow),允许第三方应用使用 SECTL Auth 账户进行用户认证。
|
||||
|
||||
### 流程特点
|
||||
|
||||
- **安全性高** - 使用授权码模式,避免 Token 暴露在浏览器端
|
||||
- **标准化** - 遵循 OAuth 2.0 RFC 6749 规范
|
||||
- **远程退登** - 支持通过 Realtime 实现跨平台同步退出
|
||||
- **可配置** - 支持自定义 Token 过期时间
|
||||
|
||||
## 授权流程
|
||||
|
||||
### 流程图
|
||||
|
||||
```
|
||||
┌─────────┐ ┌─────────────┐
|
||||
│ 用户 │ │ 第三方应用 │
|
||||
└────┬────┘ └──────┬──────┘
|
||||
│ │
|
||||
│ 1. 访问应用 │
|
||||
│───────────────────────────────────────────────>│
|
||||
│ │
|
||||
│ 2. 重定向到授权页面 │
|
||||
│<───────────────────────────────────────────────│
|
||||
│ │
|
||||
│ 3. 登录并授权 (LoginView.vue / OAuthAuthorizeView.vue)
|
||||
│───────────────────────────────────────────────>│
|
||||
│ │
|
||||
│ 4. 返回授权码 │
|
||||
│<───────────────────────────────────────────────│
|
||||
│ │
|
||||
│ 5. 用授权码换取 Token │
|
||||
│ │──────┐
|
||||
│ │ │
|
||||
│ 6. 返回 Access Token │<─────┘
|
||||
│ │
|
||||
│ 7. 使用 Token 访问用户资源 │
|
||||
│<───────────────────────────────────────────────│
|
||||
```
|
||||
|
||||
## 详细步骤
|
||||
|
||||
### 1. 引导用户到授权页面
|
||||
|
||||
当用户需要登录时,第三方应用应将用户重定向到 SECTL Auth 的授权页面。
|
||||
|
||||
**请求地址:**
|
||||
|
||||
```
|
||||
GET https://sectl.top/oauth/authorize
|
||||
```
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必填 | 类型 | 说明 |
|
||||
| ------------- | ---- | ------ | --------------------------------- |
|
||||
| client_id | ✅ | string | 平台 ID,如 `pf_AHmIhAiptyLFxk8x` |
|
||||
| redirect_uri | ✅ | string | 回调地址,必须与平台设置匹配 |
|
||||
| response_type | ✅ | string | 固定值 `code` |
|
||||
|
||||
**示例 URL:**
|
||||
|
||||
```
|
||||
https://sectl.top/oauth/authorize?client_id=pf_AHmIhAiptyLFxk8x&redirect_uri=http://localhost:5000/callback&response_type=code
|
||||
```
|
||||
|
||||
**相关代码:** [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue)
|
||||
|
||||
### 2. 用户登录与授权
|
||||
|
||||
用户将被引导至 SECTL Auth 登录页面(如果未登录):
|
||||
|
||||
1. **登录页面** ([LoginView.vue](../../src/views/LoginView.vue))
|
||||
- 用户输入邮箱密码或使用 GitHub 登录
|
||||
- 支持记住我功能
|
||||
- 检测 OAuth 参数,登录后自动跳转授权页
|
||||
|
||||
2. **授权确认页** ([OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue))
|
||||
- 显示应用名称和图标
|
||||
- 列出请求的权限范围
|
||||
- 用户可选择"授权"或"拒绝"
|
||||
|
||||
**权限范围:**
|
||||
|
||||
- 访问用户基本信息(用户名、邮箱、头像)
|
||||
- 验证用户身份
|
||||
|
||||
### 3. 获取授权码
|
||||
|
||||
用户授权后,页面将重定向到指定的回调地址:
|
||||
|
||||
```
|
||||
{redirect_uri}?code={authorization_code}
|
||||
```
|
||||
|
||||
**示例:**
|
||||
|
||||
```
|
||||
http://localhost:5000/callback?code=NjliNDIyOTYwMDE4znLUNeWM6J8ye0MC
|
||||
```
|
||||
|
||||
**授权码特性:**
|
||||
|
||||
- 有效期:10 分钟
|
||||
- 一次性使用
|
||||
- 与 `redirect_uri` 绑定
|
||||
|
||||
### 4. 换取访问令牌
|
||||
|
||||
第三方应用后端使用授权码向 SECTL Auth 换取访问令牌。
|
||||
|
||||
**请求地址:**
|
||||
|
||||
```
|
||||
POST https://sectl.top/api/oauth/token
|
||||
```
|
||||
|
||||
**请求头:**
|
||||
|
||||
```
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**请求体:**
|
||||
|
||||
```json
|
||||
{
|
||||
"grant_type": "authorization_code",
|
||||
"code": "NjliNDIyOTYwMDE4znLUNeWM6J8ye0MC",
|
||||
"client_id": "pf_AHmIhAiptyLFxk8x",
|
||||
"client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1",
|
||||
"redirect_uri": "http://localhost:5000/callback"
|
||||
}
|
||||
```
|
||||
|
||||
**参数说明:**
|
||||
|
||||
| 参数名 | 必填 | 说明 |
|
||||
| ------------- | ---- | --------------------------- |
|
||||
| grant_type | ✅ | 固定值 `authorization_code` |
|
||||
| code | ✅ | 上一步获取的授权码 |
|
||||
| client_id | ✅ | 平台 ID |
|
||||
| client_secret | ✅ | 平台密钥 |
|
||||
| redirect_uri | ✅ | 必须与授权时一致 |
|
||||
|
||||
**成功响应:**
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"refresh_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 3600
|
||||
}
|
||||
```
|
||||
|
||||
**Token 信息:**
|
||||
|
||||
| 字段 | 说明 |
|
||||
| ------------- | ----------------------------------- |
|
||||
| access_token | 访问令牌,用于调用 API |
|
||||
| refresh_token | 刷新令牌,用于获取新的 access_token |
|
||||
| token_type | 令牌类型,固定为 Bearer |
|
||||
| expires_in | 过期时间(秒) |
|
||||
|
||||
### 5. 使用访问令牌
|
||||
|
||||
获取 access_token 后,可用于调用 SECTL Auth API 获取用户信息。
|
||||
|
||||
**获取用户信息:**
|
||||
|
||||
```http
|
||||
GET https://sectl.top/api/oauth/userinfo
|
||||
Authorization: Bearer {access_token}
|
||||
```
|
||||
|
||||
**响应示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"user_id": "69bd422960018cf4d0e5",
|
||||
"email": "user@example.com",
|
||||
"name": "张三",
|
||||
"github_username": "zhangsan"
|
||||
}
|
||||
```
|
||||
|
||||
## Token 管理
|
||||
|
||||
### 过期时间配置
|
||||
|
||||
平台可配置 Token 过期时间:
|
||||
|
||||
| 令牌类型 | 默认有效期 | 说明 |
|
||||
| ------------- | --------------- | ---------------------- |
|
||||
| access_token | 3600 秒 (1小时) | 短期有效,用于访问资源 |
|
||||
| refresh_token | 长期有效 | 用于刷新 access_token |
|
||||
| 授权码 | 600 秒 (10分钟) | 一次性使用 |
|
||||
|
||||
**修改过期时间:**
|
||||
|
||||
```http
|
||||
POST https://sectl.top/api/oauth/config
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"expires_in": 86400,
|
||||
"admin_secret": "your-admin-secret"
|
||||
}
|
||||
```
|
||||
|
||||
### 刷新 Token
|
||||
|
||||
当 access_token 过期时,使用 refresh_token 获取新的令牌:
|
||||
|
||||
```http
|
||||
POST https://sectl.top/api/oauth/token
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"grant_type": "refresh_token",
|
||||
"refresh_token": "your-refresh-token",
|
||||
"client_id": "your-platform-id",
|
||||
"client_secret": "your-platform-secret"
|
||||
}
|
||||
```
|
||||
|
||||
## 远程退登
|
||||
|
||||
SECTL Auth 支持远程退登功能,当用户在 SECTL Auth 中心退出登录时,已授权的第三方应用会收到通知。
|
||||
|
||||
### 实现原理
|
||||
|
||||
1. 用户在 SECTL Auth 点击退出登录
|
||||
2. 系统创建 `logout_events` 文档
|
||||
3. 第三方应用通过 Appwrite Realtime 订阅该集合
|
||||
4. 收到退登事件后,应用执行本地退出操作
|
||||
|
||||
### 集成方式
|
||||
|
||||
详见 [平台接入指南](../platform-integration/README.md)。
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 授权错误
|
||||
|
||||
当授权失败时,将重定向到回调地址并附带错误信息:
|
||||
|
||||
```
|
||||
{redirect_uri}?error=access_denied&error_description=user+denied+authorization
|
||||
```
|
||||
|
||||
**常见错误码:**
|
||||
|
||||
| 错误码 | 说明 |
|
||||
| ------------------------- | ------------------ |
|
||||
| invalid_request | 请求参数缺失或无效 |
|
||||
| unauthorized_client | 客户端未授权 |
|
||||
| access_denied | 用户拒绝授权 |
|
||||
| unsupported_response_type | 不支持的响应类型 |
|
||||
| invalid_scope | 无效的权限范围 |
|
||||
| server_error | 服务器内部错误 |
|
||||
|
||||
### Token 错误
|
||||
|
||||
换取 Token 时的错误响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "invalid_grant",
|
||||
"error_description": "Authorization code has expired"
|
||||
}
|
||||
```
|
||||
|
||||
**常见错误码:**
|
||||
|
||||
| 错误码 | 说明 |
|
||||
| ---------------------- | ------------------------ |
|
||||
| invalid_request | 请求格式错误 |
|
||||
| invalid_client | 客户端认证失败 |
|
||||
| invalid_grant | 授权码无效或过期 |
|
||||
| unauthorized_client | 客户端无权使用此授权类型 |
|
||||
| unsupported_grant_type | 不支持的授权类型 |
|
||||
| invalid_scope | 无效的权限范围 |
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. **使用 HTTPS** - 所有 OAuth 通信必须使用 HTTPS
|
||||
2. **保护 client_secret** - 不要在客户端代码中暴露 client_secret
|
||||
3. **验证 redirect_uri** - 确保回调地址与注册时一致
|
||||
4. **使用状态参数** - 建议添加 `state` 参数防止 CSRF 攻击
|
||||
5. **及时清理** - 使用后的授权码应立即作废
|
||||
6. **安全存储** - Token 应安全存储,避免泄露
|
||||
|
||||
## 相关页面
|
||||
|
||||
- [LoginView.vue](../../src/views/LoginView.vue) - 登录页面
|
||||
- [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) - OAuth 授权页面
|
||||
- [AuthCallbackView.vue](../../src/views/AuthCallbackView.vue) - 认证回调处理
|
||||
- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) - 登录平台列表
|
||||
|
||||
## 参考文档
|
||||
|
||||
- [平台接入指南](../platform-integration/README.md)
|
||||
- [API 参考](../platform-integration/API_REFERENCE.md)
|
||||
- [故障排查](./TROUBLESHOOTING.md)
|
||||
Reference in New Issue
Block a user