权限与校验
按使用对象选择接入方式:
| 使用对象 | 校验方式 | 可用功能 |
|---|---|---|
| 客户 | 完成流星雨人机验证 | 创建短链;每条最长保留 7 天,不能通过此方式查询或删除短链。 |
| 自有服务 | 管理令牌 + 时间戳签名 | 创建、查询和删除全部短链;创建的短链不受 7 天期限限制。 |
自有服务的管理令牌由服务管理员单独提供,仅用于本地计算请求签名,不直接放入请求。此类请求无需人机验证。短链跳转接口为公开访问。
自有服务调用 POST /api/links、查询和删除接口时使用以下签名请求头。本页仅说明校验规则和示例,不包含实际令牌。
| 请求头 | 格式 | 说明 |
|---|---|---|
X-Timestamp | 10 位 Unix 秒级时间戳 | 与服务端时间相差不得超过 300 秒。 |
X-Nonce | UUID v4 | 每次请求新生成;重复使用会被拒绝。 |
X-Signature | 64 位小写或大写十六进制 | 按下方规则计算的 HMAC-SHA256。 |
请求体为空时,按空字符串计算 SHA-256。非空时,对实际发送的 UTF-8 原始请求体字节计算 SHA-256。然后按以下顺序拼接字段,各字段之间使用单个换行符(LF),末尾不加换行符:
timestamp + "\n" + nonce + "\n" + HTTP_METHOD + "\n" + PATHNAME + "\n" + body_sha256_hex
对拼接结果使用服务端密钥计算 HMAC-SHA256,再把摘要编码为十六进制,作为 X-Signature。路径只包含 URL pathname,不包含域名和查询字符串;HTTP 方法使用大写形式。
Node.js 签名示例
将密钥配置在调用方自己的环境变量中。不要把密钥放入公开网页、客户端应用或版本库。
import { createHash, createHmac, randomUUID } from "node:crypto";
function signRequest({ method, path, body = "" }) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = randomUUID();
const bodyHash = createHash("sha256").update(body, "utf8").digest("hex");
const canonical = [timestamp, nonce, method.toUpperCase(), path, bodyHash].join("\n");
const signature = createHmac("sha256", process.env.SHORTLINK_API_SECRET)
.update(canonical, "utf8").digest("hex");
return {
"X-Timestamp": timestamp,
"X-Nonce": nonce,
"X-Signature": signature,
};
}
const body = JSON.stringify({ url: "https://example.com/article" });
const headers = signRequest({ method: "POST", path: "/api/links", body });
const response = await fetch("https://s.yulovehan.top/api/links", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body,
});
接口列表
| 方法 | 路径 | 用途 | 签名 |
|---|---|---|---|
POST | /api/links | 创建短链 | 需要 |
POST | /api/links/captcha | 人机验证后创建,链接最长保留 7 天 | CAPTCHA 令牌 |
GET | /api/links/{code} | 查询短链及访问统计 | 需要 |
DELETE | /api/links/{code} | 删除短链 | 需要 |
GET | /{code} | 跳转到原始网址 | 不需要 |
签名创建短链
POST /api/links,请求体为 JSON。url 必填;code 和 expiresAt 可选。网址仅允许 HTTP 或 HTTPS;有效期使用 ISO 8601 格式且必须晚于当前时间。
{
"url": "https://example.com/articles/2026/long-address",
"code": "launch-2026",
"expiresAt": "2026-12-31T23:59:59+08:00"
}
成功返回 HTTP 201:
{
"code": "launch-2026",
"url": "https://s.yulovehan.top/launch-2026",
"targetUrl": "https://example.com/articles/2026/long-address",
"expiresAt": "2026-12-31T15:59:59.000Z"
}
省略 code 时系统自动生成短码;省略或留空 expiresAt 时短链永久有效。
人机验证后创建短链
页面使用流星雨验证码弹窗获取一次性令牌。后端再向验证服务请求校验,只有验证服务响应 JSON 中 success === true 才创建短链。验证服务不可用时按失败处理。此方式不需要 HMAC 签名,短链有效期最多 7 天:省略 expiresAt 时默认 7 天,超过 7 天的日期会自动截到最长有效期。签名 API 创建的短链不受此上限影响。
POST /api/links/captcha,请求头为 Content-Type: application/json;请求体:
{
"url": "https://example.com/article",
"code": "launch-2026",
"expiresAt": "2026-10-27T12:00:00.000Z",
"captcha_token": "完成验证后由页面取得的一次性令牌"
}
浏览器验证码 SDK:https://meteorcaptcha.yulovehan.top/captcha/loader.js。在用户操作回调中调用 Captcha.verifyModal(),从结果的 token 字段取令牌,并放入上述 captcha_token 字段。令牌由后端向 POST https://meteorcaptcha.yulovehan.top/api/v1/check 校验,请求体为 { "token": "令牌" };令牌一次性使用。
查询短链
GET /api/links/{code},签名中的 pathname 替换为实际路径,例如 /api/links/launch-2026。成功时返回 code、shortUrl、targetUrl、创建时间、有效期、点击次数和最近访问时间。
删除短链
DELETE /api/links/{code},请求体为空,签名中的 body hash 为 SHA-256 空字符串摘要。成功返回 { "deleted": true, "code": "launch-2026" }。
短链跳转
浏览器访问 GET /{code} 后,服务端增加点击次数并返回 HTTP 302。短码不存在时返回 404;短链已过期时返回 410。
错误码
| HTTP 状态 | 含义 |
|---|---|
| 400 | 参数错误、网址无效、JSON 格式错误或人机验证失败 |
| 401 | 签名无效、时间戳过期或 nonce 重复 |
| 404 | 短码不存在 |
| 405 | 当前路径不支持该 HTTP 方法 |
| 409 | 自定义短码已被占用 |
| 410 | 短链已过期 |
| 503 | 服务暂时不可用,请稍后重试 |
错误响应统一为 JSON:{ "error": { "message": "说明", "status": 400 } }。