Chhoto URL 7.10.3 REST API 使用详解

Chhoto URL 7.10.3 管理 REST API 全端点实测:X-API-Key 与会话 Cookie 双认证、11 端点全景与请求/响应结构、短链 CRUD/编辑停用/计数清零、ASCII notes 校验与双认证删除形态差异(2026-10-30 实测)。

Chhoto URL自托管RustSQLite2026/10/30

Chhoto URL 7.10.3 REST API 使用详解

目标:本文是 Chhoto URL 的 API 篇,覆盖 v7.10.3 管理接口的认证方式、全部端点、请求/响应结构与错误行为,全部场景均为容器实测原始输出(2026-10-30)。配置项口径见《Chhoto URL 7.10.3 配置参数详解》,部署与 API Key 准备见《Chhoto URL 7.10.3 Docker Compose 部署指南》。

一、API 全景与统一约定

v7.10.3 全部管理能力都走同一进程的 REST 接口(网页管理界面即该 API 的前端实现),端点总览:

方法路径认证作用
GET/api/version免认证服务端版本号
GET/api/siteurl免认证站点地址(官方注释已弃用,建议 getconfig)
GET/api/getconfig需要生效配置回显(不含敏感项)
GET/api/whoami需要当前身份(API Key/会话返回 admin)
POST/api/login免认证(即登录本身)密码换会话 Cookie
DELETE/api/logout需要注销会话
POST/api/new需要创建短链
GET/api/all需要列出全部短链(支持分页与过滤)
POST/api/expand需要查询单条短链详情
PUT/api/edit需要编辑目标/备注/启停/过期/清零计数
DELETE/api/del/{shortlink}需要删除短链

统一约定(实测归纳):请求体为 application/json;响应普遍携带 {"success": bool, "error": bool, ...} 三元结构,失败时附 reason 文案;成功创建返回 shorturl 完整地址、enabled、expiry_time。

二、认证方式实测

2.1 两种凭证

API Key(适合脚本):请求头 X-API-Key 携带环境变量 CHHOTO_API_KEY 配置的密钥:

curl -s -H "X-API-Key: $API_KEY" http://localhost:8130/api/whoami
# → admin

会话 Cookie(适合人机交互):POST /api/login 用管理密码换取签名 Cookie:

curl -s -c cookie.txt -H "Content-Type: application/json" \
  -d '{"password": "YOUR_PASS", "remember": true}' http://localhost:8130/api/login
# → {"success":true,"error":false,"reason":"Correct password!"} [200]
# cookie.txt 中出现 chhoto-url-auth=<Base64 签名串>
curl -s -b cookie.txt http://localhost:8130/api/whoami
# → admin

remember: true/false 控制会话有效期长短;两种凭证可同时可用,网页端走 Cookie、脚本端走 API Key 互不干扰。

2.2 失败行为(实测原文)

场景状态码响应
不带任何凭证访问受保护端点401纯文本 Unauthorized
API Key 错误401纯文本 Wrong API key.
会话过期/无效401纯文本 Unauthorized

2.3 登出与会话失效机制(重要发现)

DELETE /api/logout 返回 200 Logged out!,但实测登出后继续用原 Cookie 访问 /api/all 仍返回 200——会话是无状态签名 Cookie,服务端没有会话表或黑名单,logout 的实际效果依赖客户端丢弃 Cookie。真正的强制失效手段是重启容器:会话签名密钥每次启动重新生成,所有旧 Cookie 立即失效。单用户定位下这是合理设计,但「改密码踢会话」类需求要靠重启实现。

三、短链 CRUD 实测

3.1 创建:POST /api/new

# 自定义别名
curl -s -X POST -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{"longlink": "https://www.quzuo.net/", "shortlink": "quzuo-home"}' http://localhost:8130/api/new
# → {"success":true,"error":false,"shorturl":"http://192.168.1.200:8130/quzuo-home","enabled":true,"expiry_time":0}

# 不传 shortlink 自动生成(风格由 CHHOTO_SLUG_STYLE 决定)
curl -s -X POST -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{"longlink": "https://example.org/x"}' http://localhost:8130/api/new

创建路径的四种实测失败(状态码均为 400):

场景reason
别名已存在Short URL is already in use!
禁大写时提交大写别名(BadLink)Invalid shortlink!
别名含空格/斜杠等非法字符Invalid shortlink!
目标协议不在白名单(file:///etc/passwd)Invalid longlink!

别名合法字符集源码口径:a-z、0-9、-、_(开启 CHHOTO_ALLOW_CAPITAL_LETTERS 后加入大写字母)。

3.2 列表:GET /api/all

curl -s -H "X-API-Key: $API_KEY" http://localhost:8130/api/all
# → [{"shortlink":"docs","longlink":"https://www.quzuo.net","hits":7,"expiry_time":0,"enabled":true,"notes":"quzuo docs portal updated"}, ...]

支持四个查询参数(源码结构 GetReqParams,实测):

参数行为实测
filter对短链/长链/备注做模糊匹配?filter=quzuo → 3 条(shortlink、longlink、notes 各命中一部分)
page_no页码,0 基page_no=1&page_size=2 返回第 3-4 条
page_size每页条数—
page_after按游标翻页适合遍历大列表

3.3 单条查询:POST /api/expand

注意 v7.10.3 的 expand 只有 POST 可用(GET 形式实测 404),且请求体直接放短链字符串、不是 JSON 对象:

curl -s -H "X-API-Key: $API_KEY" -d "docs" http://localhost:8130/api/expand
# → {"success":true,"error":false,"longurl":"https://www.quzuo.net","hits":7,"expiry_time":0,"enabled":true,"notes":"quzuo docs portal updated"}

查询不存在的短链返回 400 {"success":false,"error":true,"reason":"The shortlink does not exist on the server!"}。源码注释标注 POST 版为 legacy(未来可能移除),升级大版本前留意变更日志。

3.4 编辑:PUT /api/edit

编辑接口一次携带全量字段(部分字段不传会按缺省覆盖,建议每次回显原值再改),请求体六字段:

字段类型作用
shortlinkstring要编辑的别名(必填,定位用)
longlinkstring新目标地址
reset_hitsbooltrue 时把访问计数清零
expiry_timeint过期时间戳(0=不过期)
enabledbool启停开关
notesstring备注,仅允许 ASCII 可打印字符
# 改目标与备注(成功返回 201,不是 200)
curl -s -w '\n[%{http_code}]' -X PUT -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{"shortlink":"editdemo","longlink":"https://example.org/edited","reset_hits":false,"expiry_time":0,"enabled":true,"notes":"after edit"}' \
  http://localhost:8130/api/edit
# → {"success":true,"error":false,"reason":"Edit was successful."} [201]

# enabled=false 停用后再访问短链 → 404(跳转直接拒绝)
curl -s -o /dev/null -w '[%{http_code}]' http://localhost:8130/editdemo
# → [404]

# reset_hits=true 清零计数(docs 原本 hits=7)
curl -s -X PUT -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{"shortlink":"docs","longlink":"https://www.quzuo.net","reset_hits":true,...}' http://localhost:8130/api/edit
# → 再 expand 确认 {"hits":0,...},清零立即生效

编辑路径的实测失败(均 400):

场景reason
notes 含非 ASCII(如中文备注)Invalid notes!
编辑不存在的别名The shortlink was not found, and could not be edited.
请求体不是合法 JSONMalformed request!

notes 的 ASCII 限制在源码 is_note_valid 中实锤(仅接受 ASCII 可打印字符),中文备注需在上游系统另行存储,这是多语言场景接入前必须知道的约束。

3.5 删除:DELETE /api/del/{shortlink}

删除端点的响应形态随认证方式变化(源码为保持向后兼容有意为之):

# API Key 认证:JSON 响应
curl -s -w '\n[%{http_code}]' -H "X-API-Key: $API_KEY" -X DELETE http://localhost:8130/api/del/editdemo
# → {"success":true,"error":false,"reason":"Deleted editdemo"} [200]

# 会话 Cookie 认证:纯文本响应
curl -s -b cookie.txt -w '\n[%{http_code}]' -X DELETE http://localhost:8130/api/del/editdemo
# → Deleted editdemo [200]

# 删除不存在的别名:404
curl -s -w '\n[%{http_code}]' -H "X-API-Key: $API_KEY" -X DELETE http://localhost:8130/api/del/nosuchlink
# → {"success":false,"error":true,"reason":"The shortlink was not found, and could not be deleted."} [404]

脚本解析响应时注意:走 API Key 拿 reason 字段,走会话 Cookie 直接拿纯文本体,二选一保持一致即可。

四、辅助端点与配置回显

三个只读端点实测:

curl -s http://localhost:8130/api/version
# → Chhoto URL v7.10.3(纯文本,免认证,健康巡检可直接用)

curl -s http://localhost:8130/api/siteurl
# → http://192.168.1.200:8130(纯文本,免认证;官方注释已弃用,建议改用 getconfig)

curl -s -H "X-API-Key: $API_KEY" http://localhost:8130/api/getconfig
# → {"version":"7.10.3","site_url":"http://192.168.1.200:8130","allow_capital_letters":false,
#    "public_mode":false,"public_mode_expiry_delay":0,"allowed_protocols":["http","ftp","magnet","https"],
#    "slug_style":"Pair","slug_length":8,"try_longer_slug":false,"frontend_page_size":10} [200]

getconfig 回显 10 项生效配置,不含密码与 API Key 等敏感项,可用于启动后核对环境变量是否按预期生效(与 C1 配置参数篇的默认值口径互查)。

五、错误速查与集成建议

全端点错误行为汇总(实测口径):

状态码触发场景响应形态
401无凭证/凭证错误访问受保护端点纯文本 Unauthorized 或 Wrong API key.
400创建/编辑参数非法、expand 不存在JSON reason 字段
404删除不存在的别名、停用链跳转JSON(API Key)/ 纯文本(会话)
201PUT /api/edit 成功JSON
200其余成功场景JSON 或纯文本(随端点/认证而异)

集成建议三点:① 脚本统一走 X-API-Key(JSON 响应形态稳定,会话形态仅适合人机交互);② 依赖 201 判断编辑成功(部分 HTTP 客户端默认只认 2xx 无妨,但不要硬编码 200);③ 批量管理用 /api/all 的 page_no/page_after 游标翻页,避免大列表一次拉全。


本文与同系列互读:选型背景见《Chhoto URL 介绍与选型指南》,部署与 API Key 配置见《Chhoto URL 7.10.3 Docker Compose 部署指南》,环境变量全集见《Chhoto URL 7.10.3 配置参数详解》。