# 用户

### 身份验证[​](https://docs.flarum.org/zh/rest-api/#%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81) <a href="#shen-fen-yan-zheng" id="shen-fen-yan-zheng"></a>

我们的单页应用使用会话 Cookies 进行 API 的身份验证。 外部程序可使用 API 密钥 或 访问令牌 的无状态身份验证。

`GET` 端点无需身份验证即可使用， 但此时只会返回游客可见的内容。 为防止 CSRF 攻击，其他端点均需身份验证方可使用。

#### API 密钥[​](https://docs.flarum.org/zh/rest-api/#api-%E5%AF%86%E9%92%A5) <a href="#api-mi-yao" id="api-mi-yao"></a>

脚本、工具与集成应用和 ArkFlarum 的交互应当采用 API 秘钥作为首选方案。

**创建**[**​**](https://docs.flarum.org/zh/rest-api/#%E5%88%9B%E5%BB%BA)

目前没有用于管理 API 密钥的操作界面，您只能在数据库 `api_keys` 表中手动创建。

以下参数可在创建时提供：

* `key`：秘钥。您需要自行生成一个独一无二的长字符串（推荐长度 40 的字母数字组合），秘钥将作为 `Authorization` 请求头的值。
* `user_id`：用户 ID，可选项。 如果设置了此值，秘钥会被充当为指定的用户。

以下属性会被自动填充，部分作为保留字段尚未使用：

* `id`：主键。由 MySQL 自动递增填写。
* `allowed_ips`：IP 白名单。保留字段，尚未使用。
* `scopes`：范围。保留字段，尚未使用。
* `created_at`：创建时间。虽然可设置任意日期值，但理应表示秘钥的创建日期。
* `last_activity_at`：上次使用时间。秘钥被使用时自动更新。

**使用**[**​**](https://docs.flarum.org/zh/rest-api/#%E4%BD%BF%E7%94%A8)

发起 API 请求时，将秘钥添加到 `Authorization` 请求头即可。 如需指定扮演用户角色，可在请求头末尾添加。

```
Authorization: Token 你的_API_秘钥_值; userId=1
```

如果在数据库中为密钥设置了 `user_id` 值，请求头中的 `userId=` 将被忽略。 否则，任何有效的用户 ID 都可起作用。

#### 访问令牌[​](https://docs.flarum.org/zh/rest-api/#%E8%AE%BF%E9%97%AE%E4%BB%A4%E7%89%8C) <a href="#fang-wen-ling-pai" id="fang-wen-ling-pai"></a>

访问令牌（Access Tokens）是基于用户的短效令牌。

这些令牌用于 Cookie 会话， 使用他们与常规会话别无二致。 用户的上次在线时间会随访问令牌的使用而更新。

**创建**[**​**](https://docs.flarum.org/zh/rest-api/#%E5%88%9B%E5%BB%BA-1)

所有用户均可创建访问令牌。 要创建令牌，请使用 `/api/token` 端点并提供用户凭证：

```
POST /api/token HTTP/1.1

{
    "identification": "JamXi[Ex]",
    "password": "Ex"
}

HTTP/1.1 200 OK

{
    "token": "YACub2KLfe8mfmHPcUKtt6t2SMJOGPXnZbqhc3nX",
    "userId": "1"
}
```

我们目前存在 3 种令牌类型，其中 2 种可以通过 REST API 创建。

* `session` 令牌在 1 小时没有活动后即会过期。 这是默认的令牌类型。
* `session_remember` 令牌在 5 年没有活动后即会过期。 在请求体中添加 `remember=1` 属性即可获取这种令牌。
* `developer` 令牌永不过期。 目前只可通过数据库手动创建这种令牌。

**所有令牌将在用户注销时一并失效**（包括 `developer` 令牌，不过我们计划改变这种状况）。

**使用**[**​**](https://docs.flarum.org/zh/rest-api/#%E4%BD%BF%E7%94%A8-1)

发起 API 请求时，将上一步取得的 `token` 添加到 `Authorization` 请求头即可：

```
Authorization: Token YACub2KLfe8mfmHPcUKtt6t2SMJOGPXnZbqhc3nX
```

#### CSRF 保护[​](https://docs.flarum.org/zh/rest-api/#csrf-%E4%BF%9D%E6%8A%A4) <a href="#csrf-bao-hu" id="csrf-bao-hu"></a>

多数 `POST`/`PUT`/`DELETE` API 端点都有 [跨站请求伪造](https://en.wikipedia.org/wiki/Cross-site_request_forgery)（Cross-site request forgery，缩写 CSRF）保护功能。 因此，要发出无状态请求，必须进行身份验证。

使用 API 密钥或访问令牌时，可跳过 CSRF 保护。

#### 注册用户[​](https://docs.flarum.org/zh/rest-api/#%E6%B3%A8%E5%86%8C%E7%94%A8%E6%88%B7) <a href="#zhu-ce-yong-hu" id="zhu-ce-yong-hu"></a>

```
POST /api/users
```

```
{
  "data": {
    "attributes": {
      "username": "JamXi[Ex]",
      "email": "arkflarum@example.com",
      "password": "Ex"
    }
  }
}
```

### 错误[​](https://docs.flarum.org/zh/rest-api/#%E9%94%99%E8%AF%AF) <a href="#cuo-wu" id="cuo-wu"></a>

ArkFlarum 使用不同的 HTTP 状态码进行错误应答，所有错误表述均符合 [JSON:API 错误规范](https://jsonapi.org/format/#errors)。

下面是您使用 REST API 时可能遇到的一些常见错误：

#### CSRF 令牌不匹配[​](https://docs.flarum.org/zh/rest-api/#csrf-%E4%BB%A4%E7%89%8C%E4%B8%8D%E5%8C%B9%E9%85%8D) <a href="#csrf-ling-pai-bu-pi-pei" id="csrf-ling-pai-bu-pi-pei"></a>

如果您收到了消息为 `csrf_token_mismatch` 的 400 HTTP 错误，这意味着 `Authorization` 请求头缺失或无效，导致 ArkFlarum 尝试通过会话 Cookie 进行身份验证。

```
{
  "errors": [
    {
      "status": "400",
      "code": "csrf_token_mismatch"
    }
  ]
}
```

#### 验证错误[​](https://docs.flarum.org/zh/rest-api/#%E9%AA%8C%E8%AF%81%E9%94%99%E8%AF%AF) <a href="#yan-zheng-cuo-wu" id="yan-zheng-cuo-wu"></a>

验证错误会返回一个 HTTP 状态码 422 的响应。 无效字段的名称会以 `pointer` 值返回。 在同一时间，单个字段可能出现多个错误。

```
{
  "errors": [
    {
      "status": "422",
      "code": "validation_error",
      "detail": "The username has already been taken.", // 用户名已被使用
      "source":{
        "pointer":"\/data\/attributes\/username"
      }
    },
    {
      "status": "422",
      "code": "validation_error",
      "detail": "The email has already been taken.", // 邮箱地址已被使用
      "source": {
        "pointer":"\/data\/attributes\/email"
      }
    }
  ]
}
```
