管理员登录(2FA 扩展)
1. 接口定位
- 接口名称: 管理员登录(2FA 扩展)
- 所属域: admin/account
- 业务目标: 校验管理员账号密码;未开启 2FA 时直接签发 token,已开启 2FA 时下发挑战凭证
2. 请求定义
- Method:
POST - Path:
/adminx/account/login - Content-Type: 推荐
application/json - operationID: 必填,请通过 Header
operationID传入 - 鉴权: 无
- 幂等性: 对同一组账号密码为准幂等;开启 2FA 时每次会生成新的 challengeID
3. 请求参数
Header 参数
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
| operationID | 是 | string | 链路追踪 ID |
| token | 否 | string | 本接口无需 |
Body 参数
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
| account | 是 | string | 管理员账号 |
| password | 是 | string | 管理员密码 |
4. 响应结构
通用响应包裹
| 字段 | 类型 | 说明 |
|---|---|---|
| errCode | int | 错误码,0 表示成功 |
| errMsg | string | 错误简述 |
| errDlt | string | 错误详情 |
| data | object | 业务数据 |
data 字段
| 字段 | 类型 | 说明 |
|---|---|---|
| needTwoFactor | bool | 是否需要二次验证 |
| challengeID | string | 二次验证挑战 ID;仅 needTwoFactor=true 时返回 |
| adminAccount | string | 管理员账号;仅 needTwoFactor=false 时返回 |
| adminToken | string | 管理员 token;仅 needTwoFactor=false 时返回 |
| adminUserID | string | 管理员 userID;仅 needTwoFactor=false 时返回 |
| nickname | string | 管理员昵称;仅 needTwoFactor=false 时返回 |
| faceURL | string | 管理员头像;仅 needTwoFactor=false 时返回 |
| level | int32 | 管理员等级;仅 needTwoFactor=false 时返回 |
| imUserID | string | 默认 OpenIM 管理员 ID;仅 needTwoFactor=false 时返回 |
| imToken | string | 默认 OpenIM 管理员 token;仅 needTwoFactor=false 时返回 |
5. 业务规则
- 登录链路会先检查管理员是否已被封禁;已封禁则直接拒绝登录。
- 若管理员未启用 2FA:返回完整登录信息(含
adminToken)。 - 若管理员已启用 2FA:
- 返回
needTwoFactor=true和challengeID; - 不返回
adminToken; - 会主动失效第一阶段临时签发的 token,避免绕过二次验证。
- 返回
- 当已开启 2FA 时,第一阶段只负责签发挑战,不代表最终登录成功;最终成功以
/adminx/account/login/totp校验通过为准。 challengeID默认有效期为 2 分钟。
登录审计说明
- 未开启 2FA 时:本接口会直接写入一次成功或失败登录审计。
- 已开启 2FA 时:
- 密码阶段失败会写入失败登录审计;
- 密码阶段成功但进入二次验证时,不会提前写入成功审计;
- 最终成功或失败会在
/adminx/account/login/totp阶段落审计。
6. 错误码与失败场景
| 错误码 | 场景 | 典型报错 |
|---|---|---|
| 1001 | Header 缺少 operationID | header must have operationID |
| 20002 | 管理员账号不存在 | AccountNotFound |
| 20001 | 管理员密码错误 | PasswordError |
| 1002 | 管理员已被封禁 | admin blocked |
| - | challenge 写入失败 | 由 Redis 客户端返回 |
7. 示例
fetch 请求示例
javascript
fetch("http://localhost:10011/adminx/account/login", {
method: "POST",
headers: {
operationID: "adminx-login-2fa-001",
"Content-Type": "application/json",
},
body: JSON.stringify({
account: "root_admin",
password: "OpenIM@123",
}),
})
.then((res) => res.json())
.then((data) => console.log(data));成功响应示例(未开启 2FA)
json
{
"errCode": 0,
"errMsg": "",
"errDlt": "",
"data": {
"needTwoFactor": false,
"adminAccount": "root_admin",
"adminToken": "eyJhbGciOi...",
"adminUserID": "1000000001",
"nickname": "System Admin",
"faceURL": "",
"level": 100,
"imUserID": "imAdmin",
"imToken": "eyJhbGciOi..."
}
}成功响应示例(已开启 2FA)
json
{
"errCode": 0,
"errMsg": "",
"errDlt": "",
"data": {
"needTwoFactor": true,
"challengeID": "f5e4f0f4d2f84d6a2b1a0f3f5f6d7c8e"
}
}8. 时序流程
- 解析请求并调用 admin 登录能力校验账号密码。
- 查询当前管理员 2FA 状态。
- 未开启 2FA:直接返回 token。
- 已开启 2FA:失效临时 token,生成 challengeID 写入 Redis,返回挑战信息。
9. 变更记录
- 2026-04-14: 补充管理员封禁拦截与登录审计语义说明。
- 2026-04-07: 首版发布,新增管理员登录(2FA 扩展)接口文档。