返回介绍

使用 REST API

发布于 2024-06-22 20:04:58 字数 12761 浏览 0 评论 0 收藏 0

Flarum 提供了 REST API,它不仅被我们的单页应用使用着,也可供外部程序调用。

我们的 API 采用 JSON:API 规范定义的最佳实践。

信息

若要扩展 REST API 以实现新的应用,请查看开发者文档《API 与数据流》。

身份验证

我们的单页应用使用会话 Cookies 进行 API 的身份验证。 外部程序可使用

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

创建

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

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

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

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

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

使用

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

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

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

访问令牌

访问令牌(Access Tokens)是基于用户的短效令牌。

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

创建

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

POST /api/token HTTP/1.1

{
    "identification": "张三",
    "password": "张三的密码"
}

HTTP/1.1 200 OK

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

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

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

所有令牌将在用户注销时一并失效(包括 developer 令牌,不过我们计划改变这种状况)。

使用

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

Authorization: Token YACub2KLfe8mfmHPcUKtt6t2SMJOGPXnZbqhc3nX

CSRF 保护

多数 POST/PUT/DELETE API 端点都有 跨站请求伪造(Cross-site request forgery,缩写 CSRF)保护功能。 因此,要发出无状态请求,必须进行身份验证。

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

端点

这部分文档仍在编写中。 我们正在研究如何为端点实现自动化文档。

每个扩展程序都可自行添加新的端点和属性,因此提供涵盖所有端点的文档。 若要查看端点,您可以使用浏览器的开发者工具检查单页应用发起的请求。

下面是一些常用接口的示例。 为方便阅读,部分 JSON 字段已略去。

列出全部主题帖

GET /api/discussions
{
  "links": {
    "first": "https://flarum.tld/api/discussions",
    "next": "https://flarum.tld/api/discussions?page%5Boffset%5D=20"
  },
  "data": [
    {
      "type": "discussions",
      "id": "227",
      "attributes": {
        "title": "出师表",
        "slug": "227-chu-shi-biao",
        "commentCount": 10,
        "participantCount": 3,
        "createdAt": "0227-01-01T00:10:30+08:00",
        "lastPostedAt": "0227-01-05T00:10:30+08:00",
        "lastPostNumber": 10,
        "canReply": true,
        "canRename": true,
        "canDelete": true,
        "canHide": true,
        "isHidden": true,
        "hiddenAt": "0227-01-01T00:10:30+08:00",
        "lastReadAt": "0227-01-01T00:10:30+08:00",
        "lastReadPostNumber": 2,
        "isApproved": true,
        "canTag": true,
        "isLocked": false,
        "canLock": true,
        "isSticky": false,
        "canSticky": true,
        "canMerge": true,
        "subscription": null
      },
      "relationships": {
        "user": {
          "data": {
            "type": "users",
            "id": "1"
          }
        },
        "lastPostedUser": {
          "data": {
            "type": "users",
            "id": "64"
          }
        },
        "tags": {
          "data": [
            {
              "type": "tags",
              "id": "3"
            }
          ]
        },
        "firstPost": {
          "data": {
            "type": "posts",
            "id": "668"
          }
        }
      }
    },
    {
      "type": "discussions",
      "id": "234",
      "attributes": {
        // [...]
      },
      "relationships": {
        // [...]
      }
    },
    // [...] 更多主题
  ],
  "included": [
    {
      "type": "users",
      "id": "1",
      "attributes": {
        "username": "Zhugeliang",
        "displayName": "诸葛亮",
        "avatarUrl": null,
        "slug": "1"
      }
    },
    {
      "type": "users",
      "id": "64",
      "attributes": {
        "username": "Flarum",
        "displayName": "Flarum",
        "avatarUrl": "https://www.wenjiangs.com/wp-content/uploads/2024/docimg4/1780-prwgmfy2smp.png",
        "slug": "64"
      }
    },
    {
      "type": "tags",
      "id": "3",
      "attributes": {
        "name": "欢迎",
        "description": "在这里发送一些有趣的玩意儿",
        "slug": "welcome",
        "color": "#888",
        "backgroundUrl": null,
        "backgroundMode": null,
        "icon": "fas fa-bullhorn",
        "discussionCount": 30,
        "position": 1,
        "defaultSort": null,
        "isChild": false,
        "isHidden": false,
        "lastPostedAt": "2022-01-05T10:20:30+00:00",
        "canStartDiscussion": true,
        "canAddToDiscussion": true,
        "isRestricted": false
      }
    },
    {
      "type": "posts",
      "id": "668",
      "attributes": {
        "number": 1,
        "createdAt": "2022-01-01T10:20:30+00:00",
        "contentType": "comment",
        "contentHtml": "<p>你好,世界!</p>"
      }
    },
    // [...] 其他包含内容
  ]
}

发布主题

POST /api/discussions
{
  "data":{
    "type": "discussions",
    "attributes": {
      "title": "这里是标题",
      "content": "你好,世界!"
    },
    "relationships": {
      "tags": {
        "data": [
          {
            "type": "tags",
            "id": "1"
          }
        ]
      }
    }
  }
}

服务器响应含有新主题的 ID:

{
  "data": {
    "type": "discussions",
    "id": "42",
    "attributes": {
      "title": "这里是标题",
      "slug": "42-gu-ding-lian-jie",
      "commentCount": 1
      // [...] 其他属性
    },
    "relationships": {
      "posts": {
        "data": [
          {
            "type": "posts",
            "id": "58"
          }
        ]
      },
      "user": {
        "data": {
          "type": "users",
          "id": "1"
        }
      },
      // [...] 其他关联内容
    }
  },
  "included":[
    {
      "type": "posts",
      "id": "38",
      "attributes": {
        "number": 1,
        "contentType": "comment",
        "contentHtml": "\u003Cp\u003E你好,世界!\u003C\/p\u003E"
        // [...] 其他属性
      }
    }
    // [...] 其他包含内容
  ]
}

注册用户

POST /api/users
{
  "data": {
    "attributes": {
      "username": "YongHuMing",
      "email": "[email protected]",
      "password": "MiMa"
    }
  }
}

错误

Flarum 使用不同的 HTTP 状态码进行错误应答,所有错误表述均符合 JSON:API 错误规范

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

CSRF 令牌不匹配

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

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

验证错误

验证错误会返回一个 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"
      }
    }
  ]
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文