You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

6.3 KiB

OAuth2 API 接口文档

创建日期:2026-05-26


概述

OAuth2 模块提供标准化的第三方登录认证功能,支持多种 OAuth Provider,采用配置驱动的架构设计。

Base URL: /api/auth/oauth


接口列表

方法 路径 说明
GET /:provider/authorize 生成授权 URL,重定向到 Provider
GET /:provider/callback Provider 回调,处理 token 交换
POST /bind 已登录用户绑定 OAuth 账号
DELETE /:provider/unbind 解绑 OAuth 账号
GET /bindings 获取当前用户的绑定列表
GET /:provider/status 查询某 Provider 的绑定状态

1. 授权接口

生成授权 URL

GET /api/auth/oauth/:provider/authorize

路径参数:

参数 类型 必填 说明
provider string Provider 名称,如 githubgoogle

查询参数:

参数 类型 必填 说明
bind number 绑定模式,传递 1 表示已登录用户绑定操作
redirect_uri string 自定义回调跳转地址

响应: 302 Found

Location: https://github.com/login/oauth/authorize?client_id=xxx&redirect_uri=xxx&scope=xxx&state=xxx

错误响应:

状态码 错误码 说明
400 OAUTH_PROVIDER_NOT_FOUND 不支持的 Provider

2. 回调接口

处理 Provider 回调

GET /api/auth/oauth/:provider/callback

路径参数:

参数 类型 必填 说明
provider string Provider 名称

查询参数:

参数 类型 必填 说明
code string Provider 授权码
state string 防止 CSRF 的状态令牌

响应: 302 Found

登录成功:

Location: /auth/login?oauth_success=1

绑定成功:

Location: /profile?bind_success=1

错误响应:

状态码 错误码 说明
400 OAUTH_STATE_INVALID state 验证失败
400 OAUTH_STATE_EXPIRED state 已过期
400 OAUTH_TOKEN_EXCHANGE_FAILED token 交换失败
400 OAUTH_USER_INFO_FAILED 获取用户信息失败
400 OAUTH_ALREADY_BIND 账号已绑定其他用户
400 OAUTH_BINDING_USER_MISMATCH 绑定用户不匹配

错误跳转示例:

Location: /auth/login?oauth_error=OAUTH_STATE_EXPIRED

3. 绑定接口

绑定 OAuth 账号

POST /api/auth/oauth/bind

请求体:

{
  "bindingToken": "string"
}
参数 类型 必填 说明
bindingToken string 回调时返回的临时 binding token

响应:

{
  "success": true,
  "binding": {
    "provider": "github",
    "username": "username"
  }
}

错误响应:

状态码 错误码 说明
400 OAUTH_BINDING_TOKEN_INVALID binding token 无效或已过期
401 UNAUTHORIZED 未登录

4. 解绑接口

解绑 OAuth 账号

DELETE /api/auth/oauth/:provider/unbind

路径参数:

参数 类型 必填 说明
provider string Provider 名称

响应:

{
  "success": true
}

错误响应:

状态码 错误码 说明
400 OAUTH_LAST_BIND 至少保留一个绑定方式(不能解绑最后一个)
401 UNAUTHORIZED 未登录

5. 绑定列表接口

获取绑定列表

GET /api/auth/oauth/bindings

响应:

{
  "bindings": [
    {
      "id": 1,
      "provider": "github",
      "username": "username",
      "email": "user@example.com",
      "avatar": "https://avatars.githubusercontent.com/u/xxx",
      "boundAt": "2026-05-26T10:00:00.000Z"
    }
  ]
}

6. 绑定状态接口

查询单个 Provider 绑定状态

GET /api/auth/oauth/:provider/status

路径参数:

参数 类型 必填 说明
provider string Provider 名称

响应:

{
  "bound": true,
  "binding": {
    "id": 1,
    "username": "username"
  }
}

或未绑定:

{
  "bound": false
}

错误码详解

错误码 HTTP 状态码 说明
OAUTH_PROVIDER_NOT_FOUND 400 请求的 Provider 未注册
OAUTH_STATE_INVALID 400 state 令牌无效,可能被篡改
OAUTH_STATE_EXPIRED 400 state 超过 5 分钟有效期
OAUTH_TOKEN_EXCHANGE_FAILED 400 与 Provider 交换 access_token 失败
OAUTH_USER_INFO_FAILED 400 从 Provider 获取用户信息失败
OAUTH_ALREADY_BIND 400 该第三方账号已绑定其他用户
OAUTH_BINDING_USER_MISMATCH 400 绑定操作用户与当前登录用户不匹配
OAUTH_BINDING_TOKEN_INVALID 400 binding token 无效或已过期
OAUTH_LAST_BIND 400 无法解绑最后一个 OAuth 账号
UNAUTHORIZED 401 需要登录才能进行此操作

使用示例

前端调用流程

1. 发起 GitHub 登录

// 方法一:直接跳转(后端处理一切)
window.location.href = '/api/auth/oauth/github/authorize';

// 方法二:打开弹窗
const popup = window.open('/api/auth/oauth/github/authorize', 'oauth', 'width=600,height=700');

2. 回调后处理

// 在登录页或 profile 页检测参数
const url = new URL(window.location.href);
if (url.searchParams.get('oauth_success') === '1') {
  // 刷新用户状态
  await refreshSession();
  // 跳转到首页或用户中心
  router.push('/');
}

if (url.searchParams.get('bind_success') === '1') {
  // 刷新绑定列表
  await fetchBindings();
}

if (url.searchParams.get('oauth_error')) {
  const error = url.searchParams.get('oauth_error');
  alert(`登录失败: ${error}`);
}

3. 获取绑定列表

const { data } = await useFetch('/api/auth/oauth/bindings');
const bindings = data.value?.bindings ?? [];

4. 解绑操作

await $fetch('/api/auth/oauth/github/unbind', { method: 'DELETE' });
// 刷新绑定列表
await fetchBindings();