POST/api/v1/auth/mfa/verify登录中的 MFA 校验

对未达标的尝试追加 MFA 因素(默认 60 分)。必须携带登录流程返回的尝试工单;服务端校验当前环境指纹与尝试一致。

Request

Headers

NameData TypeRequiredDescription
Content-TypestringYes请求体内容类型(默认值 "application/json")
type RequestHeaders = {
  /** 请求体内容类型,默认值 "application/json" */
  Content-Type: string
}
{
  "Content-Type": "application/json"
}

Body

NameData TypeRequiredDescription
attemptTicketstringYes登录流程签发的尝试工单
codestringYesMFA 验证码(TOTP 6 位)
type RequestBody = {
  /** 登录流程签发的尝试工单 */
  attemptTicket: string
  /** MFA 验证码(TOTP 6 位) */
  code: string
}
{
  "attemptTicket": "atk_9f2c7be14d0a53e8",
  "code": "384127"
}

Response

Body

NameData TypeRequiredDescription
statusstringYespending 未达标 / satisfied 已达标并签发会话
attemptTicketstringNo尝试工单;pending 时必返,后续因素验证继续携带
nextFactorsarrayNopending 时按配置仍可选的因素
sessionTokenstringNo会话令牌(不透明);satisfied 时返回
refreshTokenstringNo刷新令牌;satisfied 时返回
sessionIdstringNo会话 ID;satisfied 时返回
expiresAtstringNo会话过期时间;satisfied 时返回
type LoginResultDTO = {
  /** pending 未达标 / satisfied 已达标并签发会话 */
  status: string
  /** 尝试工单;pending 时必返,后续因素验证继续携带 */
  attemptTicket?: string
  /** pending 时按配置仍可选的因素 */
  nextFactors?: string[]
  /** 会话令牌(不透明);satisfied 时返回 */
  sessionToken?: string
  /** 刷新令牌;satisfied 时返回 */
  refreshToken?: string
  /** 会话 ID;satisfied 时返回 */
  sessionId?: string
  /** 会话过期时间;satisfied 时返回 */
  expiresAt?: string
}
{
  "status": "pending",
  "attemptTicket": "atk_9f2c7be14d0a53e8",
  "nextFactors": [
    "otp",
    "mfa",
    "captcha"
  ]
}

HTTP Code

HTTP Status Meaning Notes
200 成功 MFA 因素计入尝试;达标即签发会话并消费工单
400 工单或验证码无效 尝试工单无效、指纹不符或 MFA 码错误

Response Code

响应使用统一信封 {id, code, messages, result},其 code 字段:

code Meaning Notes
0 成功 返回登录结果
2007 尝试工单无效 工单不存在、过期或已消费
2008 环境指纹不匹配 当前请求与尝试创建时的指纹不一致
2204 MFA 码错误 验证码不正确或所属因素不匹配

Examples

POST /api/v1/auth/mfa/verify
Content-Type: application/json

{
  "attemptTicket": "atk_9f2c7be14d0a53e8",
  "code": "384127"
}
{
  "id": "01JD8SH5S0N7M1X0",
  "code": 0,
  "messages": [],
  "result": {
    "status": "satisfied",
    "sessionToken": "st_7c1f9e05b28d4a63",
    "refreshToken": "rt_46a9c7e015283d5b",
    "sessionId": "01JD8SEGVK6MZ7W3Q4RT5N8YB2",
    "expiresAt": "2026-11-13T08:00:00Z"
  }
}