身份验证和 API 密钥
Discuse API 会使用 API 密钥对每个请求进行身份验证。请在 X-API-Key 请求头中发送它(也可以作为 JSON 请求体中的 api_key 字段发送)。密钥以 disc_ 前缀开头,绑定到单个项目,并且只会在创建时完整显示一次。本指南将介绍如何获取、使用、保护和轮换 API 密钥。
Discuse 身份验证是如何工作的?
每次 API 调用都必须包含有效的 API 密钥。Discuse 会用它来:
- 根据你项目的配额跟踪用量
- 对每个密钥应用速率限制,防止滥用
- 将请求关联到正确的项目及其设置
- 控制对你账户资源的访问
获取你的 API 密钥
第 1 步:创建账户
如果你还没有账户,请在 discuse.com 注册 Discuse 账户。你可以从免费的 Basic 方案开始,该方案包含每月一定额度的 API 请求,并可使用文本、垃圾内容、语言和图片检测功能。当前各方案的限制请参见定价页面。
第 2 步:访问控制台
登录后,进入你的控制台。在导航菜单中查找“API Keys”或“Developer”部分。
第 3 步:生成新密钥
点击“Create New API Key”,并可选择为该密钥填写名称或描述。如果你创建了多个密钥,这有助于识别每个密钥的用途。
新的 API 密钥只会显示一次。请立即复制并安全保存——之后你将无法再次查看完整密钥。
使用你的 API 密钥
在每个请求的 X-API-Key 请求头中包含你的 API 密钥:
curl -X POST https://api.discuse.com/api/v2/check \
-H "Content-Type: application/json" \
-H "X-API-Key: disc_aB3dEf6GhIjKlMnOpQrStUvWxYz012345" \
-d '{
"content": {
"text": "Content to analyze"
}
}'
你也可以不使用请求头,而是在 JSON 请求体中通过 api_key 字段传递密钥——但更推荐使用请求头,这样密钥就不会出现在请求体日志中。
JavaScript 示例
const response = await fetch('https://api.discuse.com/api/v2/check', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.DISCUSE_API_KEY
},
body: JSON.stringify({
content: { text: 'Content to analyze' }
})
});
Python 示例
import requests
import os
response = requests.post(
'https://api.discuse.com/api/v2/check',
headers={
'Content-Type': 'application/json',
'X-API-Key': os.environ['DISCUSE_API_KEY']
},
json={
'content': {'text': 'Content to analyze'}
}
)
API 密钥安全最佳实践
绝不要在客户端代码中暴露密钥
API 密钥绝不应包含在浏览器中运行的 JavaScript 里。任何查看你页面源代码的人都能看到客户端代码。
// WRONG - Don't do this!
const API_KEY = 'disc_aB3dEf6...'; // Exposed in browser
// CORRECT - Use a backend proxy
const response = await fetch('/api/moderate', {
method: 'POST',
body: JSON.stringify({ text: userInput })
});
使用环境变量
将 API 密钥存储在环境变量中,而不是放进代码库:
# .env file (add to .gitignore!)
DISCUSE_API_KEY=disc_aB3dEf6GhIjKlMnOpQrStUvWxYz012345
// Access in Node.js
const apiKey = process.env.DISCUSE_API_KEY;
定期轮换密钥
请定期轮换你的 API 密钥,尤其是在你怀疑密钥可能已经泄露时:
- 生成新的 API 密钥
- 更新你的应用以使用新密钥
- 验证一切是否正常运行
- 撤销旧密钥
注意:由于已验证的密钥会被缓存,已撤销的密钥最多可能仍可使用约 5 分钟。规划轮换时,请考虑这段短暂的重叠时间,而不要预期能够瞬时切换。
为不同环境使用不同密钥
为开发、预发布和生产环境创建不同的 API 密钥:
| 环境 | 密钥用途 |
|---|---|
| 开发 | 测试和本地开发 |
| 预发布 | 生产前测试 |
| 生产 | 线上应用流量 |
这样一来,你可以撤销已泄露的密钥,而不影响其他环境。
速率限制是如何工作的?
速率限制是按 API 密钥计算的,而不是按方案计算的。每个密钥在创建时都会设置每分钟请求数(RPM)限制;如果你没有指定,默认值为每分钟 60 次请求。同一账户下的不同密钥可以有不同的限制,因此你可以为高吞吐服务设置比一次性集成更高的 RPM。
当某个密钥超过其 RPM 限制时,请求会失败,并返回 HTTP 429 Too Many Requests 状态,其 message 会说明已超出速率限制。速率限制计数器会在滚动的一分钟窗口内重置。
处理速率限制
遇到 429(以及临时性的 5xx)时,请退避后重试。由于窗口为一分钟,从约一秒开始并逐步增长的指数退避通常效果很好:
async function checkWithRetry(content, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch('https://api.discuse.com/api/v2/check', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.DISCUSE_API_KEY
},
body: JSON.stringify({ content })
});
if (response.status === 429 || response.status >= 500) {
const delay = 1000 * Math.pow(2, attempt); // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
return response.json();
}
throw new Error('Max retries exceeded');
}
我可能会收到哪些错误响应?
| 情况 | HTTP 状态 |
|---|---|
| 请求格式错误(内容为空、文本超过 10,000 个字符、URL 过多) | 400 请求验证 |
| API 密钥缺失或无效 | 401 |
| 该密钥超出速率限制 | 429 |
| 计费周期配额已用尽 | 200,包含 message 和 usage(不是错误状态) |
配额用尽有意不作为 HTTP 错误处理:/api/v2/check 响应仍会返回 200,并包含 has_violations: false、描述配额已用尽的 message,以及显示 api_requests_remaining: 0 的 usage 对象。请检查这些字段,而不是依赖状态码。身份验证失败会返回 401,速率限制会返回 429,请求验证失败会返回 400。完整列表请参见错误和响应代码参考文档。
管理多个密钥
对于较大的团队或复杂应用,你可能需要多个 API 密钥:
多个密钥的使用场景
- 按环境划分的密钥:为开发、预发布和生产环境使用不同密钥
- 按服务划分的密钥:为不同微服务使用不同密钥
- 按团队划分的密钥:按团队隔离用量,便于内部计费
- 临时密钥:为承包商或集成使用的短期密钥
密钥管理最佳实践
- 为密钥取描述性名称:"Production - User Service", "Staging - Backend"
- 记录密钥用途:维护每个密钥在何处使用的记录
- 设置告警:监控异常使用模式
- 定期审计:每季度检查并清理未使用的密钥