## 登录认证 (`auth`)

登录、刷新令牌、退出、改口令、动态口令(TOTP)、找回密码、图形验证码与超管代登录。登录接口无需认证。

鉴权: 无需鉴权 · 文档: https://www-demo.kuxitong.com/zh/docs/api/auth

### GET `/api/v2/auth/captcha`

获取图形验证码 · 鉴权: 无需鉴权

```sh
curl "https://panel.example.com/api/v2/auth/captcha"
```

### POST `/api/v2/auth/login`

登录 · 鉴权: 无需鉴权

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `captcha_code` | string |  | 图形验证码上显示的字符。 |
| `captcha_id` | string |  | 图形验证码 id,来自 GET /auth/captcha;连续登录失败后必填。 |
| `password` | string | 有 | 登录口令。 |
| `totp_code` | string |  | 动态口令(TOTP)的 6 位当前码,或一个未用过的恢复码(XXXXX-XXXXX,用后作废);账号启用动态口令时必填。 |
| `username` | string | 有 | 用户名 |
| `verify_code` | string |  | 登录二次验证码。账号开了邮件/短信验证码登录(login_verify)时必填,先经 POST /verify-codes(purpose=login)获取。 |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/login"
```

### POST `/api/v2/auth/logout`

退出登录 · 鉴权: 用户

```sh
curl -X POST "https://panel.example.com/api/v2/auth/logout" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### PUT `/api/v2/auth/password`

修改口令 · 鉴权: 用户

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `new_password` | string | 有 | 新口令,8 到 128 个字符。 |
| `old_password` | string | 有 | 原口令。 |

```sh
curl -X PUT "https://panel.example.com/api/v2/auth/password" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/auth/password-reset`

找回密码 · 鉴权: 无需鉴权

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `channel` | string | 有 | 按邮箱还是手机号找回。 可选值: ["email","sms"] |
| `code` | string | 有 | 发到 target 的验证码(POST /verify-codes,purpose=reset_password)。 |
| `new_password` | string | 有 | 新口令,8 到 128 个字符。 |
| `target` | string | 有 | 账号绑定的邮箱或手机号。 |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/password-reset" \
  -H "Content-Type: application/json" \
  -d '{"channel":"email","code":"123456","new_password":"${NEW_PASSWORD}","target":"user@example.com"}'
```

### POST `/api/v2/auth/refresh`

刷新令牌 · 鉴权: 无需鉴权

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `refresh_token` | string | 有 | 刷新令牌,用来换新的一对令牌。 |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/refresh"
```

### POST `/api/v2/auth/sso`

超管代登录 · 鉴权: 无需鉴权

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `sso_ticket` | string | 有 | 超管签发的登录票:licwire 信封(kind sso_ticket)字节的 base64url(无填充)。 |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/sso" \
  -H "Content-Type: application/json" \
  -d '{"sso_ticket":"eyJib2R5Ijp7fX0"}'
```

### POST `/api/v2/auth/switch`

管理员切换到用户 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `user_id` | integer | 有 | 用户 ID |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/switch" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id":2}'
```

### POST `/api/v2/auth/switch-login`

凭切换票登录 · 鉴权: 无需鉴权

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `switch_ticket` | string | 有 | 管理员换到的一次性切换票。 |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/switch-login"
```

### POST `/api/v2/auth/switch-ticket`

管理员换一张切换到用户的一次性票 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `user_id` | integer | 有 | 用户 ID |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/switch-ticket" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id":2}'
```

### POST `/api/v2/auth/totp`

生成动态口令密钥 · 鉴权: 用户

```sh
curl -X POST "https://panel.example.com/api/v2/auth/totp" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### PUT `/api/v2/auth/totp`

启用动态口令 · 鉴权: 用户

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `code` | string | 有 | 发到 target 的验证码(POST /verify-codes,purpose=reset_password)。 |

```sh
curl -X PUT "https://panel.example.com/api/v2/auth/totp" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### DELETE `/api/v2/auth/totp`

关闭动态口令 · 鉴权: 用户

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `code` | string | 有 | 发到 target 的验证码(POST /verify-codes,purpose=reset_password)。 |

```sh
curl -X DELETE "https://panel.example.com/api/v2/auth/totp" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

登录认证对象:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `access_token` | string |  | 访问令牌,放在 Authorization: Bearer 里调用接口。 |
| `captcha_code` | string |  | 图形验证码上显示的字符。 |
| `captcha_id` | string |  | 图形验证码 id,来自 GET /auth/captcha;连续登录失败后必填。 |
| `channel` | string | 有 | 按邮箱还是手机号找回。 可选值: ["email","sms"] |
| `code` | string | 有 | 发到 target 的验证码(POST /verify-codes,purpose=reset_password)。 |
| `expires_in` | integer |  | access token 有效秒数。 |
| `id` | string |  | 登录时作为 captcha_id 回传;一次性,验一次即作废(不论对错)。 |
| `image` | string |  | PNG 的 data URI。 |
| `key` | string |  | base32 密钥(只在这里返回一次)。 |
| `must_change_password` | boolean |  | 只在登录响应里出现;true = 该账号还在用装机生成的初始口令(/root/gocdn-admin.pass),须先改口令(PUT /auth/password)再用,改过后不再出现。 |
| `new_password` | string | 有 | 新口令,8 到 128 个字符。 |
| `old_password` | string | 有 | 原口令。 |
| `otpauth_uri` | string |  | otpauth:// 地址,用认证器 App 扫码添加。 |
| `password` | string | 有 | 登录口令。 |
| `recovery_codes` | string[] |  | 8 个一次性恢复码(XXXXX-XXXXX),只在启用成功时返回这一次。 |
| `refresh_token` | string |  | 刷新令牌,用来换新的一对令牌。 |
| `sso_ticket` | string | 有 | 超管签发的登录票:licwire 信封(kind sso_ticket)字节的 base64url(无填充)。 |
| `switch_ticket` | string | 有 | 管理员换到的一次性切换票。 |
| `target` | string | 有 | 账号绑定的邮箱或手机号。 |
| `token_type` | string |  | 令牌类型,固定为 Bearer。 |
| `totp_code` | string |  | 动态口令(TOTP)的 6 位当前码,或一个未用过的恢复码(XXXXX-XXXXX,用后作废);账号启用动态口令时必填。 |
| `user_id` | integer | 有 | 用户 ID |
| `username` | string | 有 | 用户名 |
| `verify_code` | string |  | 登录二次验证码。账号开了邮件/短信验证码登录(login_verify)时必填,先经 POST /verify-codes(purpose=login)获取。 |
