5.1 认证、签名与工作区
认证、签名与工作区
受保护 API 的认证优先级为:完整签名请求、Authorization: Bearer 中的登录 JWT、API Bearer Token。签名头只要齐全就按签名验证,不会再回退到 Bearer。
登录 JWT
curl -sS https://s.example.com/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"demo-admin","password":"<password>"}'响应 data.token 用作:
Authorization: Bearer <login-jwt>
X-Workspace-Id: 1
POST /api/v1/auth/logout 会删除当前用户的 API Token 记录;调用前应确认这符合你的 Token 生命周期预期。
API Bearer Token
在“系统设置 → API Token”创建 bearer 类型,明文 Token 仅在创建响应中返回一次:
curl -sS 'https://s.example.com/api/v1/short_links?page=1&page_size=20' \
-H 'Authorization: Bearer <api-token>' \
-H 'X-Workspace-Id: 1'Bearer 凭据会随每次请求传输,因此必须使用 HTTPS,按用途拆分 Token,并设置合理过期时间。
HMAC-SHA256 请求签名
创建 signature 类型 Token 后会获得一次性显示的 app_id 和 app_secret。请求头为:
X-App-Id: app_xxx
X-Signature: <hex-hmac-sha256>
X-Timestamp: <unix-seconds>
X-Nonce: <non-empty-random-string>
X-Workspace-Id: 1
待签名字符串:
UPPER_METHOD + request_path + sorted_top_level_params_json + timestamp + nonce参数规则:
- Query 参数始终加入;单值是字符串,多值是字符串数组。
POST、PUT、PATCH且Content-Type包含application/json时,再把 JSON 对象的顶层字段合并进去;Body 同名字段覆盖 Query。- 顶层键按字典序排序,JSON 紧凑编码且不转义 HTML 字符;空参数是
{}。 request_path不含 scheme、host 和 query,例如/api/v1/short_links。- 时间戳允许服务器当前时间前后 300 秒。
- 当前版本只要求 nonce 非空,服务端没有持久化 nonce 去重;调用方仍应每次生成随机 nonce,但不能把它当成完整的服务端防重放存储。
Python 示例:
import hashlib
import hmac
import json
import time
import uuid
import requests
method = "POST"
path = "/api/v1/short_links"
body = {"domain": "s.example.com", "original_url": "https://example.com/a"}
timestamp = int(time.time())
nonce = uuid.uuid4().hex
params_json = json.dumps(dict(sorted(body.items())), separators=(",", ":"), ensure_ascii=False)
message = f"{method}{path}{params_json}{timestamp}{nonce}"
signature = hmac.new(b"<app-secret>", message.encode(), hashlib.sha256).hexdigest()
response = requests.post(
"https://s.example.com" + path,
json=body,
headers={
"X-App-Id": "app_xxx",
"X-Signature": signature,
"X-Timestamp": str(timestamp),
"X-Nonce": nonce,
"X-Workspace-Id": "1",
},
timeout=10,
)
response.raise_for_status()
print(response.json())工作区与权限
| 角色 | 读取业务资源 | 管理短链/Campaign/Tag | 管理域名、用户、Token、成员 |
|---|---|---|---|
owner |
是 | 是 | 是 |
admin |
是 | 是 | 是 |
member |
是 | 是 | 否 |
viewer |
是 | 否 | 否 |
系统管理员标识与工作区角色是不同概念。资源接口还会按 workspace_id 隔离数据;不要只依赖前端隐藏菜单。
OIDC
登录页通过 GET /api/v1/auth/login-options 获取 OIDC 状态;浏览器使用 /api/v1/auth/oidc/authorize 和回调完成登录。管理接口见用户、Token 与系统管理。