docs: publish open-source guides and MIT license
This commit is contained in:
1 parent
1f01140b1d
commit
b1faab339e
10 files changed
+530
-86
No files matched your search
+86
@@ -0,0 +1,86 @@
|
||||
# API 与认证
|
||||
|
||||
[返回项目首页](../README.zh-CN.md) · [开发指南](development.md)
|
||||
|
||||
API 基础路径为 `/api/v1`。完整端点、请求字段、权限和响应以 [OpenAPI 源文件](../internal/api/openapi.json)为准,运行中的实例在 `GET /api/v1/openapi.json` 提供同一文档。测试 `TestOpenAPICoversRoutes` 核对路由覆盖。
|
||||
|
||||
## 脚本接入
|
||||
|
||||
在「设置 → 账户与安全 → API 令牌」创建只读或读写令牌。受保护 API 只接受 `Authorization: Bearer <token>`,不接受 Cookie,也不要将主令牌放进 URL。
|
||||
|
||||
以下只读示例从环境变量读取凭据:
|
||||
|
||||
```sh
|
||||
# 先在本机环境中设置 RAWMARK_URL 和 RAWMARK_TOKEN,不要提交真实值。
|
||||
curl --fail-with-body \
|
||||
-H "Authorization: Bearer $RAWMARK_TOKEN" \
|
||||
"$RAWMARK_URL/api/v1/tree"
|
||||
```
|
||||
|
||||
`rm_` API 令牌在服务端只存哈希,保留 read/write 权限。只读令牌可读取笔记、搜索和执行只读 POST 导出,不能写入;API 令牌不能管理账户、令牌、维护或资源票据,不能为自身扩权。管理操作需要浏览器登录会话。
|
||||
|
||||
## JSON 与 HTTP 语义
|
||||
|
||||
普通 JSON 成功响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"data": { "ok": true },
|
||||
"message": "成功"
|
||||
}
|
||||
```
|
||||
|
||||
`code = 0` 表示成功,非零表示失败;失败时 `message` 是可展示的原因。保留真实 HTTP 状态,不把错误全部转为 200。通用错误码为 HTTP 状态乘 100,特定业务码如下:
|
||||
|
||||
| HTTP | code | 含义 |
|
||||
| --- | --- | --- |
|
||||
| 400 | 40001 | 验证码错误、无效或已使用 |
|
||||
| 400 | 40002 | 验证码过期 |
|
||||
| 400 | 40003 | 修改密码时当前密码错误,不清理身份 |
|
||||
| 401 | 40101 | 登录密码错误 |
|
||||
| 412 | 41200 | 文件版本冲突,当前版本在 `data.rev` |
|
||||
|
||||
401 表示需要重新认证;403 表示当前身份没有权限,不能据此注销用户。维护输入或备份内容无效返回 400,占用或空间不足返回 503,文件系统/数据库内部故障返回 500。
|
||||
|
||||
**文件原文、下载、WebSocket、204 及 OpenAPI 文档不包 JSON 外壳**。`GET /files/{path}` 返回 Markdown 原文和 `ETag`;`PUT /files/{path}` 接收原文,成功返回包含 `rev` 的 JSON。用 `If-Match: "rev"` 防止覆盖新版本,或 `If-None-Match: *` 要求目标不存在;都不带会直接覆盖,不适合需要冲突保护的写入。
|
||||
|
||||
## 浏览器登录
|
||||
|
||||
实例没有用户名、注册或角色系统。尚未初始化时,`POST /auth/setup` 使用 `{ password }` 设置密码并返回会话;已经初始化的实例不能再次初始化。
|
||||
|
||||
正常登录流程:
|
||||
|
||||
1. `POST /auth/captcha` 获取 `{ captchaId, imageDataUrl, expiresAt }`。
|
||||
2. 展示图片,用户填写密码与六位数字验证码。
|
||||
3. `POST /auth/login` 提交 `{ password, captchaId, captchaCode }`。
|
||||
4. 成功返回 `{ token, expiresAt }`,再通过 `GET /auth/me` 恢复真实身份与权限。
|
||||
|
||||
以上字段均位于普通响应的 `data` 中。刷新验证码时传 `{ replaceId }` 使旧挑战失效。挑战绑定来源,五分钟过期;每次登录提交一次性消费,即使密码或验证码错误也不能重用,失败必须刷新。签发与登录均保留限流。
|
||||
|
||||
`rms_` 浏览器会话 Token 保存在 localStorage 的 `rawmark.token`,固定三十天有效、不滑动续期,服务端仅存哈希。退出调用 `POST /auth/logout`,服务端撤销成功返回 204 后才清理本地身份;请求失败时保留身份并提示错误,不能仅删除本地 Token 宣称注销完成。
|
||||
|
||||
localStorage 可被同源脚本读取;有完整前端权限的插件必须视为可信代码,不能承诺凭据隔离。
|
||||
|
||||
## 原生资源与事件
|
||||
|
||||
原生图片、字体、插件模块与浏览器 WebSocket 不能统一设置认证头,通过 `POST /auth/tickets` 获取受限资源 URL;主 Token 不进入 URL。票据服务端只保存哈希,每次读取检查父会话,父会话退出后即失效。
|
||||
|
||||
- 图片/字体票据不超过父会话有效期。
|
||||
- 插件票据额外绑定插件 ID 和版本,支持相对模块导入。
|
||||
- 事件握手票据一分钟有效、仅消费一次;已连接事件仍会检查父凭据。
|
||||
- 脚本 WebSocket 客户端可以通过 Bearer 请求头继续连接 `/api/v1/events`。
|
||||
|
||||
私有响应使用 `Cache-Control: no-store` 与 `Referrer-Policy: no-referrer`,API 和私有资源不进入 PWA 静态缓存。代理日志也需脱敏,见[部署文档](deployment.md#https-与反向代理)。
|
||||
|
||||
## 前端请求责任
|
||||
|
||||
请求处理、认证与路由守卫分别位于 `http/`、`pinia/` 和 `router/`。匿名跳登录并保留合法站内回跳,拒绝外部地址与循环跳转。401 清理当前身份、权限与动态路由,403 保留身份。
|
||||
|
||||
每次替换或退出会话更新代号、取消旧请求。用户信息、路由安装、异步响应与排队写入均须检查所属会话;旧结果按 Axios 取消语义拒绝,不能覆盖或注销新身份,也不提示取消错误。
|
||||
|
||||
同一错误只由一个责任层提示。请求默认负责展示,已有行内状态、保存重试或批量汇总的 API 使用 `errorOwner: 'caller'`;失败依然 reject,不以空列表或默认值伪装成功。
|
||||
|
||||
## 旧客户端迁移
|
||||
|
||||
统一协议需要前后端同时更新,不保留 Cookie/Bearer 或两种 JSON 格式兜底。旧 `rm_` API 令牌无需重建,但调用方要改为读取 `{ code, data, message }` 中的 `data`;文件及导出字节语义不变。旧浏览器页面需重新登录,不能连接新旧混用的后端。
|
||||
Reference in new issue
Block a user