鉴权指南
1. 概述
七牛云 CDN OpenAPI 采用 双域名 + 双鉴权 架构,两种鉴权方式与请求域名严格绑定,不可混用。
| 请求域名 | 鉴权方式 | 覆盖模块 | QPS |
|---|---|---|---|
api.qiniu.com |
Qiniu 鉴权 (请求内容签名) | 域名管理 、域名配置 | 10 |
fusion.qiniuapi.com |
QBox 鉴权 (路径签名) | 用量统计、运营统计、缓存管理、证书管理、日志下载 | 5-10 |
2. 接入准备
2.1 密钥获取
七牛云控制台 > 个人中心 > 密钥管理,获取 AccessKey (AK) 和 SecretKey (SK)。
安全提示: SK 为核心密钥,严禁在客户端暴露,所有鉴权操作必须在服务端完成。
2.2 环境要求
- 通信协议: 仅 HTTPS (443 端口)
- 字符编码: UTF-8
- 请求格式: POST/PUT 请求体为紧凑 JSON (无格式化空格/换行)
- 必须携带:
Content-Type: application/json - 时间同步: 服务器 UTC 时间偏差 ≤ 30 秒
3. Qiniu 鉴权详解
3.1 适用范围
3.2 签名算法
对应 SDK QiniuMacAuth.token_of_request,基于完整请求内容签名。
签名原始串拼接规则:
data = "{Method} {PathWithQuery}" # 例: "POST /domain/test.example.com"
data += "\nHost: {Host}" # 例: "\nHost: api.qiniu.com"
data += "\nContent-Type: {ContentType}" # 例: "\nContent-Type: application/json"
data += "\n{X-Qiniu-Headers}" # 例: "\nX-Qiniu-Date: 20260213T120000Z"
data += "\n\n" # 固定两个换行
data += "{Body}" # POST/PUT 请求体 (GET/DELETE 为空)
签名生成:
Sign = HmacSHA1(data, SK)
Token = AK + ":" + urlsafe_base64(Sign)
Header = "Authorization: Qiniu {Token}"
URL 安全 Base64: 标准 Base64 后将 + 替换为 -,/ 替换为 _,保留尾部 =。
3.3 生成步骤
-
拼接 Method + Path
"PUT /domain/test.example.com/cache" -
追加 Host
"\nHost: api.qiniu.com" -
追加 Content-Type (有请求体时)
"\nContent-Type: application/json" -
追加 X-Qiniu-Date (参与签名的自定义头)
"\nX-Qiniu-Date: 20260213T120000Z" -
固定追加两个换行
"\n\n" -
追加请求体 (POST/PUT 时追加紧凑 JSON,GET/DELETE 不追加)
{"cacheControls":[{"time":3,"timeunit":0,"type":"all","rule":"*"}],"ignoreParam":true} -
HmacSHA1 签名 + URL 安全 Base64 编码
3.4 请求示例
curl -X PUT 'https://api.qiniu.com/domain/test.example.com/cache' \
-H 'Content-Type: application/json' \
-H 'X-Qiniu-Date: 20260213T120000Z' \
-H 'Authorization: Qiniu <AK>:<urlsafe_b64_sign>' \
-d '{"cacheControls":[{"time":3,"timeunit":0,"type":"all","rule":"*"}],"ignoreParam":true}'
3.5 关键注意
- Body 参与签名时 必须与实际发送的请求体完全一致 (字节级)
Content-Type: application/octet-stream的请求体不参与签名X-Qiniu-Date为 UTC 时间,格式YYYYMMDDTHHMMSSZ,偏差 ≤ 30 秒
4. QBox 鉴权详解
4.1 适用范围
4.2 签名算法
对应 SDK Auth.token_of_request,基于接口路径签名,轻量高效。
签名原始串拼接规则:
data = "{Path}\n" # 例: "/v2/tune/refresh\n"
重要:
application/json类型的请求体 不参与 QBox 签名。仅application/x-www-form-urlencoded类型的 body 才追加到签名串。CDN 接口均为 JSON,因此 QBox 签名仅含路径。
签名生成:
Sign = HmacSHA1(data, SK)
Token = AK + ":" + urlsafe_base64(Sign)
Header = "Authorization: QBox {Token}"
4.3 生成步骤
-
拼接签名数据:
{接口路径}\n- 路径含 query 参数,如
/sslcert?marker=&limit=10\n - 不含域名,仅路径部分
- 路径含 query 参数,如
-
HmacSHA1 签名: 使用 SK 作为密钥
-
拼接 Token:
AK:urlsafe_base64(签名结果)
4.4 请求示例
# 缓存刷新
curl -X POST 'https://fusion.qiniuapi.com/v2/tune/refresh' \
-H 'Content-Type: application/json' \
-H 'Authorization: QBox <AK>:<urlsafe_b64_sign>' \
-d '{"urls":["http://test.example.com/file.jpg"]}'
# 获取证书列表 (GET 无 body)
curl -X GET 'https://fusion.qiniuapi.com/sslcert?marker=&limit=10' \
-H 'Authorization: QBox <AK>:<urlsafe_b64_sign>'
4.5 关键注意
- Token 与接口路径 强绑定,不可跨接口复用
- 路径含
?query部分时,query 也参与签名 - JSON body 不参与签名,因此修改请求体不影响 Token
5. 响应规范
5.1 成功响应
带 code 字段 (fusion.qiniuapi.com 接口):
{
"code": 200,
"data": {
...
}
}
不带 code 字段 (api.qiniu.com 部分接口,如 GET /domain):
{
"name": "test.example.com",
"cname": "xxx.cdn.dnsv1.com",
"protocol": "https",
...
}
api.qiniu.com 的 GET 域名详情接口直接返回域名信息,无
code包装层。
5.2 失败响应
{
"code": 400020,
"error": "域名未备案"
}
5.3 鉴权相关错误码
| HTTP 状态码 | 业务 code | 含义 | 排查方向 |
|---|---|---|---|
| 401 | 401001 | 签名不匹配 | 检查签名原始串拼接、AK/SK 正确性 |
| 401 | 401002 | 鉴权头无效 | 检查 Authorization 格式、空格位置 |
| 403 | 403024 | QPS 超限 | 降低请求频率,api 10 QPS / fusion 5-10 QPS |
6. SDK 接入 (推荐)
七牛官方 SDK 已封装签名生成、参数校验、异常处理,无需手动编写鉴权代码。
| 语言 | SDK 文档 |
|---|---|
| Python | Python SDK |
| Go | GO SDK |
| Java | JAVA SDK |
| Node.js | Node.js SDK |
| PHP | PHP SDK |
| C# | C# SDK |
| C/C++ | C/C++ SDK |
| Rudy | Rudy SDK |
建议: 优先使用 SDK,避免手动签名的格式错误、时间偏差等问题。
7. 常见错误排查
7.1 通用问题
| 现象 | 原因 | 解决 |
|---|---|---|
| 401 所有接口 | AK/SK 错误 | 核对控制台密钥 |
| 401 特定接口 | 鉴权方式与域名不匹配 | api→Qiniu,fusion→QBox |
| 401 间歇性 | 服务器时间不同步 | 同步 NTP,确保 UTC 偏差 ≤ 30s |
7.2 Qiniu 鉴权排查
| 现象 | 原因 | 解决 |
|---|---|---|
| 签名始终不匹配 | Body 签名与发送不一致 | 确保签名用的 body 字符串与实际发送完全一致 |
| PUT 请求 401 | 签名串缺少 Content-Type | 有请求体时必须追加 Content-Type 行 |
| GET 请求 401 | 签名串多了 body | GET/DELETE 不追加 body |
7.3 QBox 鉴权排查
| 现象 | 原因 | 解决 |
|---|---|---|
| Token 跨接口失败 | Token 与路径强绑定 | 每个接口单独生成 Token |
| 带 query 参数时 401 | 签名路径不含 query | 路径必须包含 ?query 部分 |
| POST 接口 401 | 误将 JSON body 加入签名 | JSON body 不参与 QBox 签名 |