HMAC 认证与安全
使用 FastOG 的 HMAC-SHA256 认证来保护您的 HMAC 签名 OG 图片 URL。本指南涵盖签名、验证和排查每个请求的步骤,让您能够即时生成动态 Open Graph 图片——支持订阅门控,且渲染次数不限(无月度渲染配额,也无超额计费)。注册后选择一个 Dynamic API 套餐,然后在仪表盘中创建您的 API 密钥和 HMAC 密钥(付费 API 渲染无广告)。在您的服务器上完成一次签名,几分钟内即可完成集成。
🚀 快速入门
初次接触 HMAC 签名? 从这里开始:
- 快速入门指南 — 5 分钟内完成配置并运行
- JavaScript 教程 — 面向 Node.js/Next.js 开发者的完整指南
- 所有框架教程 — 选择你的技术栈:
📚 文档索引
核心概念
教程
-
JavaScript/Node.js 教程 — 综合指南,涵盖:
- 快速入门(5 分钟)
- Next.js App Router(3 种模式)
- Next.js Pages Router
- Express.js 后端
- 原生 Node.js
- 前端集成模式(SSG、SSR、客户端)
- 测试与调试
- 常见陷阱
快速参考
算法
method = "GET"
path = "/api/v1/og"
canonicalQuery = every query param EXCEPT `s` (including `key`): array values sorted too; each pair rfc3986Encode(key)=rfc3986Encode(value); pairs sorted lexicographically and joined with "&"
message = method + path + "\n" + canonicalQuery
signature = hex(HMAC-SHA256(message, hmac_secret))
URL: /api/v1/og?title=Hello&key=sk_quick_123abc&s=<signature>
查询参数
| 参数 | 描述 | 示例 |
|---|---|---|
key |
完整 API 密钥 | sk_quick_123abc |
s |
HMAC-SHA256 签名(64 位十六进制字符) | 9f8a1b2c3d4e... |
错误代码
| 代码 | HTTP 状态 | 描述 |
|---|---|---|
missing_signature |
401 | 缺少 key 或 s 参数 |
invalid_signature |
401 | 签名不匹配 |
🎯 使用场景
博客文章
为博客文章生成动态 OG 图片:
javascript
const ogUrl = generateSignedOgUrl({
template: "blog",
title: post.title,
subtitle: post.excerpt,
author: post.author.name,
});
// <meta property="og:image" content="{ogUrl}" />
电商产品
为产品页面创建 OG 图片:
javascript
const ogUrl = generateSignedOgUrl({
template: "ecommerce",
title: product.name,
price: product.price,
image: product.image,
});
客户评价
为评价引用生成 OG 图片:
javascript
const ogUrl = generateSignedOgUrl({
template: "testimonial",
author_name: user.name,
author_avatar: user.avatarUrl,
quote: user.bio,
});
🔐 安全性
最佳实践
- 安全存储密钥 — 使用环境变量或密钥管理器
- 切勿在客户端代码中暴露 HMAC 密钥 — 仅在服务器端签名
- 使用 HTTPS — 防止中间人攻击
- 定期轮换密钥 — 尤其是在密钥泄露时
- 监控签名失败 — 反复失败可能表明存在攻击
- 按用户隔离 — 每个 API 密钥拥有独立的 HMAC 密钥
获取您的 HMAC 密钥
- 前往 仪表盘 → API 密钥
- 创建新的 API 密钥
- 复制 HMAC 密钥(仅显示一次!)
- 存储到环境变量中
bash
# .env
FASTOG_HMAC_SECRET=<your-64-char-hex-secret>
🧪 测试
生成测试 URL
bash
# Node.js
node -e "
const crypto = require('crypto');
const enc = (s) => encodeURIComponent(s).replace(/[!'()*]/g, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase());
const all = { title: 'Test', key: 'sk_quick_123abc' };
const pairs = [];
for (const [k, v] of Object.entries(all)) for (const vv of Array.isArray(v) ? v : [v]) pairs.push(enc(k) + '=' + enc(vv));
pairs.sort();
const canonical = pairs.join('&');
const sig = crypto.createHmac('sha256', 'YOUR_HMAC_SECRET').update('GET/api/v1/og\n' + canonical).digest('hex');
console.log('https://fastog.com/api/v1/og?title=Test&key=sk_quick_123abc&s=' + sig);
"
使用 curl 测试
bash
curl "https://fastog.com/api/v1/og?title=Test&key=sk_quick_123abc&s=<signature>"
预期响应
- ✅ 有效签名 → 返回 OG 图片(若模板参数无效则返回 422)
- ❌ 无效签名 →
{"code": "invalid_signature"} - ❌ 缺少参数 →
{"code": "missing_signature"}
🛠 故障排查
签名不匹配
- 请确认您使用的是正确的 HMAC 密钥(在仪表盘中检查 API 密钥)
- 请检查规范查询字符串:除
s之外的所有查询参数(包括key),值需按 RFC3986 编码,键需按字典序排序 - 请确认签名是小写十六进制格式(64 个字符)
📖 其他资源
❓ 常见问题
问:为什么使用查询参数而不是请求头?
答:OG 图片由社交网络爬虫(LinkedIn、Twitter、Facebook)获取,这些爬虫不会发送自定义请求头。签名必须放在 URL 中。
问:同一个签名可以用于多个请求吗?
答:可以。签名是根据确切的查询(不含 s)计算得出的,因此只要参数不变,同一个签名 URL 就一直有效。更改任何参数(包括 key)后,都必须重新签名。
问:所有模板的请求都需要签名吗?
答:是的。所有对 /api/v1/og 的请求都需要 HMAC 签名。
问:如果我的 HMAC 密钥泄露了怎么办?
答:请在仪表盘中撤销该 API 密钥并创建一个新的。每个 API 密钥都有自己独立的 HMAC 密钥。
问:我可以为内部服务禁用 HMAC 验证吗?
答:请联系支持团队获取定制方案。所有公共 API 端点都必须进行 HMAC 验证。
🆘 支持
需要帮助?
- 查看 JavaScript 教程 获取完整的代码示例
- 查阅 HMAC 签名指南 了解算法细节
- 联系支持团队:[email protected]
相关链接
- 文档 — 所有 FastOG 指南与参考
- 免费 OG 图片测试工具 — 无需账户即可预览
- 快速入门指南 — 5 分钟内上手
- HMAC 签名指南 — 算法详情
- HMAC 验证 — 服务端验证