API AK/SK 签名接入指南
功能说明
美图开放平台 API 支持使用 Access Key(AK)和 Secret Key(SK)进行请求认证。调用方按照本页规则对 HTTP 方法、路径、查询参数、请求头和请求正文进行规范化,并使用 SDK-HMAC-SHA256 生成 Authorization 请求头。
AK/SK 认证适用于 body 不超过 12M 的请求。body 超过 12M 时,应按照对应能力 API 文档使用 Token 认证。SK 应保存在服务端且不得写入客户端代码。
接入前准备
| 项目 | 说明 |
|---|---|
| AK | 应用的 Access Key,用于标识调用方 |
| SK | 与 AK 配对的 Secret Key,用于计算签名 |
| 请求 URL | 对应能力 API 文档提供的最终 HTTPS 地址 |
| HTTP 方法 | 接口规定的 GET、POST 或其他方法 |
| 请求参数 | 最终查询参数、请求头和请求 body |
签名前需完成以下处理:
- 按照能力 API 文档构造最终 URL、查询参数和请求字段。
- 将 JSON body 序列化为最终 UTF-8 字节。签名和发送必须使用相同字节,签名后不得再次序列化或修改 body。
- 设置与 URL 一致的
Host。JSON 请求还应按照接口要求设置Content-Type。 - 设置 UTC 格式的
X-Sdk-Date,或由签名 SDK 自动生成。
本文示例使用同步任务提交地址:https://openapi.meitu.com/api/v1/sdk/sync/push。
签名请求组成
规范请求由以下六部分组成,各部分之间使用换行符 \n 分隔:
CanonicalRequest =
HTTPMethod + "\n" +
CanonicalURI + "\n" +
CanonicalQueryString + "\n" +
CanonicalHeaders + "\n" +
SignedHeaders + "\n" +
PayloadHashHTTPMethod
使用实际发送的 HTTP 方法,例如 GET 或 POST。方法值需与实际请求完全一致。
CanonicalURI
使用 URL 的绝对路径部分,并按照 RFC 3986 进行路径编码和规范化。CanonicalURI 必须以 / 结尾;若实际请求路径不以 / 结尾,仅在签名计算时补充 /,实际发送的 URL 保持不变。
/api/v1/sdk/sync/push/CanonicalQueryString
无查询参数时使用空字符串。有查询参数时,参数名和值分别按 UTF-8 和 RFC 3986 进行百分号编码;A-Z、a-z、0-9、-、_、.、~ 不编码。空格编码为 %20,空值保留等号,例如 marker=。参数按编码后的名称升序排列,并使用 & 连接。
CanonicalHeaders
参与签名的请求头名称转换为小写,请求头值删除首尾空白,再按小写名称升序排列。每项写为 name:value,各项之间用换行符 \n 分隔,最后一项不追加换行符。按上方公式拼接时,CanonicalHeaders 与 SignedHeaders 之间仅有一个换行符,不插入空行。X-Sdk-Date 必须参与签名;常见 JSON 请求还包括 host 和 content-type。
SignedHeaders
将参与签名的请求头名称按照与 CanonicalHeaders 相同的顺序使用分号连接:
content-type;host;x-sdk-datePayloadHash
默认对最终请求 body 字节计算 SHA-256,并使用小写十六进制表示:
PayloadHash = LowercaseHex(SHA256(RequestBodyBytes))空 body 使用以下摘要:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855当对应能力 API 明确支持 body 不参与签名时,可设置 X-Sdk-Content-Sha256: UNSIGNED-PAYLOAD,并在 PayloadHash 位置使用字面量 UNSIGNED-PAYLOAD。该请求头本身仍需加入 CanonicalHeaders 和 SignedHeaders。
签名计算步骤
1. 计算规范请求摘要
HashedCanonicalRequest = LowercaseHex(SHA256(UTF8(CanonicalRequest)))2. 构造待签字符串
StringToSign =
"SDK-HMAC-SHA256" + "\n" +
XSdkDate + "\n" +
HashedCanonicalRequestXSdkDate 必须与请求头 X-Sdk-Date 的值相同。
3. 计算签名
Signature = LowercaseHex(HMAC-SHA256(UTF8(SecretKey), UTF8(StringToSign)))4. 生成 Authorization
AuthorizationFields =
"SDK-HMAC-SHA256 Access=" + AccessKey +
", SignedHeaders=" + SignedHeaders +
", Signature=" + Signature
Authorization = "Bearer " + Base64(UTF8(AuthorizationFields))将生成结果作为 Authorization 请求头发送。
完整请求示例
以下示例向同步任务提交接口发送 POST 请求。body 包含 task、task_type、init_images、params 和 sync_timeout 五个顶层字段。params 的值是 JSON 字符串;sync_timeout: 30 为示例值,实际字段和值以对应能力 API 文档为准。
最终 body 为以下单行 UTF-8 字符串,不包含尾随换行:
{"task":"/v1/replace-with-product-task","task_type":"formula","init_images":[{"url":"https://example.com/input.jpg","profile":{"media_profiles":{"media_data_type":"url"},"version":"v1"}}],"params":"{\"parameter\":{\"rsp_media_type\":\"url\"}}","sync_timeout":30}body 的 SHA-256 为:
e8c94cde52db9a0ac0a58d0927cc65176707ba57ec5530367fa1dd971664b534请求信息如下:
POST /api/v1/sdk/sync/push HTTP/1.1
Host: openapi.meitu.com
Content-Type: application/json
X-Sdk-Date: 20260824T010203Z
{"task":"/v1/replace-with-product-task","task_type":"formula","init_images":[{"url":"https://example.com/input.jpg","profile":{"media_profiles":{"media_data_type":"url"},"version":"v1"}}],"params":"{\"parameter\":{\"rsp_media_type\":\"url\"}}","sync_timeout":30}对应的 CanonicalRequest 为:
POST
/api/v1/sdk/sync/push/
content-type:application/json
host:openapi.meitu.com
x-sdk-date:20260824T010203Z
content-type;host;x-sdk-date
e8c94cde52db9a0ac0a58d0927cc65176707ba57ec5530367fa1dd971664b534CanonicalRequest 不包含额外尾随换行,其 SHA-256 为:
55b1ca679a9a69e295a8a0295951d4ea60b28917495d8b3ca476734b1c7bbf4e对应的 StringToSign 为:
SDK-HMAC-SHA256
20260824T010203Z
55b1ca679a9a69e295a8a0295951d4ea60b28917495d8b3ca476734b1c7bbf4e使用实际 AK、SK 和上述 SignedHeaders 计算 Signature 后,生成请求头:
Authorization: Bearer <base 64_AUTHORIZATION />示例中的时间、任务名称、图片地址和业务参数均需替换为实际请求值。任一值变化后均需重新计算签名。
请求时间要求
X-Sdk-Date 使用 UTC 时间,格式为 YYYYMMDDTHHMMSSZ:
20260824T010203ZAPI 网关会校验请求时间与接收时间的偏差。调用方系统时钟应保持同步,每次请求均应使用当前时间生成签名。请求重试时需重新生成 X-Sdk-Date 和 Authorization。
常见错误
| 错误现象 | 检查项 |
|---|---|
| 签名验证失败 | 检查 AK/SK 是否配对,HTTP 方法、URL、查询参数、已签请求头和 body 是否与签名输入一致 |
| 路径签名不一致 | 检查 CanonicalURI 是否以 / 结尾;实际请求 URL 不应因签名规范化而增加尾斜杠 |
| 查询参数签名不一致 | 检查 RFC 3986 编码、空格 %20、空值等号和参数排序;签名后不得修改 query |
| 请求头签名不一致 | 检查 Host、Content-Type、X-Sdk-Date 的名称、值和 SignedHeaders 顺序 |
| body 摘要不一致 | 检查签名与发送是否使用同一份 UTF-8 字节,是否发生再次序列化、换行变化或编码变化 |
UNSIGNED-PAYLOAD 验签失败 | 检查接口是否支持该方式,请求头名称和值是否正确,并确认该请求头已参与签名 |
| 请求时间错误 | 检查系统时钟、UTC 格式以及是否复用了旧的 X-Sdk-Date 或 Authorization |
| body 超过限制 | AK/SK 认证仅支持 12M 以内的 body;超过限制时按照能力 API 文档使用 Token 认证 |