授权模块

授权模块涵盖账号登录、Token 生命周期、第三方平台 OAuth 登录/绑定、企业 SSO,以及 RBAC 角色权限控制。


2.1 账号登录与 Token 管理

获取 RSA 公钥

所有涉及密码传输的接口(登录、注册、修改密码、重置密码)均不得明文传输密码。客户端需先获取服务端 RSA 公钥,用公钥加密密码后再发送;服务端用对应私钥解密后再做 bcrypt 哈希处理。

GET /api/v1/auth/public-key

无需认证,可公开访问。

响应:

{
  "code": 0,
  "data": {
    "key_id": "rsa_key_20240101_001",
    "public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...\n-----END PUBLIC KEY-----",
    "algorithm": "RSA/ECB/PKCS1Padding",
    "expires_at": "2024-01-01T12:30:00Z"
  }
}
字段 说明
key_id 公钥标识,传密码时须一并携带,服务端据此找到对应私钥
public_key PEM 格式 RSA 公钥(2048 bit)
algorithm 加密算法:RSA/ECB/PKCS1Padding
expires_at 公钥有效期 30 分钟,过期需重新获取

前端加密示例(JavaScript):

import JSEncrypt from 'jsencrypt'

const encryptPassword = (plainPassword, publicKey) => {
  const encrypt = new JSEncrypt()
  encrypt.setPublicKey(publicKey)
  return encrypt.encrypt(plainPassword) // 返回 Base64 字符串
}

// 使用示例
const { key_id, public_key } = await fetch('/api/v1/auth/public-key').then(r => r.json()).then(r => r.data)
const encryptedPassword = encryptPassword('Aa123456!', public_key)
// 登录时传入 key_id + encryptedPassword

账号密码登录

POST /api/v1/auth/login

密码安全: password 字段必须使用 RSA 公钥加密后传输,不得明文传输。请先调用 GET /auth/public-key 获取公钥。

{
  "email": "user@example.com",
  "key_id": "rsa_key_20240101_001",
  "password": "Base64(RSA_ENCRYPT('Aa123456!', public_key))"
}
字段 类型 必填 说明
email string 登录邮箱
key_id string 公钥标识,从 GET /auth/public-key 获取
password string RSA 加密后的 Base64 字符串

响应:

{
  "code": 0,
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refresh_token": "rt_01HX...",
    "token_type": "Bearer",
    "expires_in": 7200,
    "user": {
      "user_id": "u_01HX...",
      "email": "user@example.com",
      "user_type": "personal",
      "membership_level": "basic"
    }
  }
}

HTTP 状态码: 200 成功,401 账号或密码错误,400 key_id 无效或已过期,1102 账号已冻结


手机号验证码登录

POST /api/v1/auth/login/phone

{
  "phone": "13800138000",
  "sms_code": "123456"
}

登出

POST /api/v1/auth/logout

将当前 access_token 加入 Redis 黑名单,立即失效。

响应: {"code": 0, "message": "success"}


刷新 Token

POST /api/v1/auth/refresh

{ "refresh_token": "rt_01HX..." }

响应:

{
  "code": 0,
  "data": {
    "access_token": "eyJhbGci...(新)",
    "expires_in": 7200
  }
}

找回密码

POST /api/v1/auth/forgot-password

{ "email": "user@example.com" }

向邮箱发送重置链接,链接有效期 30 分钟。

POST /api/v1/auth/reset-password

密码安全: new_password 必须使用 RSA 公钥加密后传输。

{
  "token": "reset_token_from_email",
  "key_id": "rsa_key_20240101_001",
  "new_password": "Base64(RSA_ENCRYPT('Bb654321!', public_key))"
}

查询当前用户权限

GET /api/v1/auth/me/permissions

{
  "code": 0,
  "data": {
    "roles": ["user", "enterprise_admin"],
    "permissions": ["chat:use", "model:list", "billing:view", "member:manage"]
  }
}

2.2 短信验证码

发送短信验证码

POST /api/v1/common/sms/send

{
  "phone": "13800138000",
  "purpose": "login"
}
purpose 说明
login 登录验证
register 注册验证
reset_password 找回密码
change_phone 更换手机号

频率限制: 同手机号 60 秒内只能发送 1 次,每日最多 10 次。

验证短信验证码

POST /api/v1/common/sms/verify

{
  "phone": "13800138000",
  "code": "123456",
  "purpose": "login"
}

2.3 第三方平台 OAuth 登录

支持个人用户和企业用户分别接入不同第三方平台,统一走 OAuth 2.0 / OIDC 协议。

获取授权跳转 URL

GET /api/v1/auth/oauth/{provider}/authorize

查询参数 必填 说明
redirect_uri 回调地址
state 防 CSRF 随机串

响应:

{
  "code": 0,
  "data": {
    "authorize_url": "https://open.weixin.qq.com/connect/qrconnect?..."
  }
}

处理授权回调

POST /api/v1/auth/oauth/{provider}/callback

{
  "code": "auth_code_from_provider",
  "state": "state_string"
}

响应(首次登录自动注册):

{
  "code": 0,
  "data": {
    "is_new_user": true,
    "access_token": "eyJhbGci...",
    "refresh_token": "rt_01HX...",
    "expires_in": 7200,
    "user": {
      "user_id": "u_01HX...",
      "nickname": "张三",
      "avatar": "https://...",
      "bound_provider": "wechat"
    }
  }
}

移动端登录

POST /api/v1/auth/oauth/{provider}/mobile

{
  "code": "js_code_from_wechat_mp"
}

适用于微信小程序 wx.login() 返回的 code,直接换取平台 Token。

支持的第三方平台(provider)

provider 平台 适用用户 说明
wechat 微信(扫码登录) 个人 微信开放平台 OAuth
wechat_mp 微信小程序 个人 js_code 换 openid
alipay 支付宝 个人 支付宝授权登录
github GitHub 个人/企业 GitHub OAuth App
google Google 个人/企业 Google OIDC
dingtalk 钉钉 企业 钉钉扫码/免登
feishu 飞书 企业 飞书 OAuth 2.0
wecom 企业微信 企业 企业微信网页授权
ldap LDAP / AD 企业 企业内网目录
saml SAML 2.0 企业 自定义企业 SSO

2.4 第三方账号绑定与解绑

查询已绑定列表

GET /api/v1/auth/bindings

{
  "code": 0,
  "data": {
    "bindings": [
      {
        "provider": "wechat",
        "provider_user_id": "oXXXxx...",
        "nickname": "微信昵称",
        "avatar": "https://...",
        "bound_at": "2024-01-01T00:00:00Z"
      },
      {
        "provider": "github",
        "provider_user_id": "12345678",
        "nickname": "user123",
        "bound_at": "2024-02-01T00:00:00Z"
      }
    ]
  }
}

绑定第三方账号

POST /api/v1/auth/bindings/{provider}

{
  "code": "auth_code_from_provider",
  "state": "state_string"
}

解绑第三方账号

DELETE /api/v1/auth/bindings/{provider}

注意: 若账号仅通过此第三方登录且未设置密码,解绑前需先设置密码,否则返回 400


2.5 企业 SSO 配置

查询 SSO 配置

GET /api/v1/enterprise/sso

创建 SSO 配置

POST /api/v1/enterprise/sso

{
  "type": "saml",
  "idp_metadata_url": "https://idp.company.com/metadata.xml",
  "attribute_mapping": {
    "email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
    "name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
  }
}

type 枚举:saml / oidc / ldap

更新 SSO 配置

PUT /api/v1/enterprise/sso

删除 SSO 配置

DELETE /api/v1/enterprise/sso

测试 SSO 连通性

POST /api/v1/enterprise/sso/test

{
  "code": 0,
  "data": {
    "status": "success",
    "latency_ms": 128,
    "user_count": 150
  }
}

2.6 RBAC 角色权限管理

角色列表

GET /admin/v1/roles

{
  "code": 0,
  "data": {
    "items": [
      {
        "role_id": "role_admin",
        "name": "超级管理员",
        "description": "拥有所有权限",
        "is_system": true,
        "permission_count": 48,
        "user_count": 3
      }
    ]
  }
}

创建角色

POST /admin/v1/roles

{
  "name": "财务审核员",
  "description": "可查看账务和审核开票申请"
}

更新角色

PUT /admin/v1/roles/{role_id}

删除角色

DELETE /admin/v1/roles/{role_id}

注意: 系统内置角色(is_system: true)不可删除。

查询角色权限

GET /admin/v1/roles/{role_id}/permissions

{
  "code": 0,
  "data": {
    "permissions": [
      "accounting:view",
      "accounting:reconcile",
      "invoice:process"
    ]
  }
}

配置角色权限

PUT /admin/v1/roles/{role_id}/permissions

{
  "permissions": ["accounting:view", "invoice:process"]
}

查询用户角色

GET /admin/v1/users/{user_id}/roles

分配用户角色

PUT /admin/v1/users/{user_id}/roles

{ "roles": ["role_finance_reviewer"] }

2.7 管理端登录(独立认证流程)

步骤一:账号密码登录

POST /admin/v1/auth/login

{
  "username": "admin@example.com",
  "password": "AdminPass123!"
}

响应:

{
  "code": 0,
  "data": {
    "temp_token": "tmp_01HX...",
    "expires_in": 300,
    "require_2fa": true,
    "2fa_type": "totp"
  }
}

步骤二:2FA 验证

POST /admin/v1/auth/2fa/verify

{
  "temp_token": "tmp_01HX...",
  "code": "123456"
}

响应: 返回正式 access_token(8 小时有效,IP 绑定)

管理端登出

POST /admin/v1/auth/logout

管理端 Token 刷新

POST /admin/v1/auth/refresh

管理端 Token 无法静默刷新,过期后需重新完成完整登录流程(含 2FA)。