授权模块
授权模块涵盖账号登录、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 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)。