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 方法接口规定的 GETPOST 或其他方法
请求参数最终查询参数、请求头和请求 body

签名前需完成以下处理:

  1. 按照能力 API 文档构造最终 URL、查询参数和请求字段。
  2. 将 JSON body 序列化为最终 UTF-8 字节。签名和发送必须使用相同字节,签名后不得再次序列化或修改 body。
  3. 设置与 URL 一致的 Host。JSON 请求还应按照接口要求设置 Content-Type
  4. 设置 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" +
    PayloadHash

HTTPMethod

使用实际发送的 HTTP 方法,例如 GETPOST。方法值需与实际请求完全一致。

CanonicalURI

使用 URL 的绝对路径部分,并按照 RFC 3986 进行路径编码和规范化。CanonicalURI 必须以 / 结尾;若实际请求路径不以 / 结尾,仅在签名计算时补充 /,实际发送的 URL 保持不变。

/api/v1/sdk/sync/push/

CanonicalQueryString

无查询参数时使用空字符串。有查询参数时,参数名和值分别按 UTF-8 和 RFC 3986 进行百分号编码;A-Za-z0-9-_.~ 不编码。空格编码为 %20,空值保留等号,例如 marker=。参数按编码后的名称升序排列,并使用 & 连接。

CanonicalHeaders

参与签名的请求头名称转换为小写,请求头值删除首尾空白,再按小写名称升序排列。每项写为 name:value,各项之间用换行符 \n 分隔,最后一项不追加换行符。按上方公式拼接时,CanonicalHeaders 与 SignedHeaders 之间仅有一个换行符,不插入空行。X-Sdk-Date 必须参与签名;常见 JSON 请求还包括 hostcontent-type

SignedHeaders

将参与签名的请求头名称按照与 CanonicalHeaders 相同的顺序使用分号连接:

content-type;host;x-sdk-date

PayloadHash

默认对最终请求 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" +
    HashedCanonicalRequest

XSdkDate 必须与请求头 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 包含 tasktask_typeinit_imagesparamssync_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
e8c94cde52db9a0ac0a58d0927cc65176707ba57ec5530367fa1dd971664b534

CanonicalRequest 不包含额外尾随换行,其 SHA-256 为:

55b1ca679a9a69e295a8a0295951d4ea60b28917495d8b3ca476734b1c7bbf4e

对应的 StringToSign 为:

SDK-HMAC-SHA256
20260824T010203Z
55b1ca679a9a69e295a8a0295951d4ea60b28917495d8b3ca476734b1c7bbf4e

使用实际 AK、SK 和上述 SignedHeaders 计算 Signature 后,生成请求头:

Authorization: Bearer <base 64_AUTHORIZATION />

示例中的时间、任务名称、图片地址和业务参数均需替换为实际请求值。任一值变化后均需重新计算签名。

请求时间要求

X-Sdk-Date 使用 UTC 时间,格式为 YYYYMMDDTHHMMSSZ

20260824T010203Z

API 网关会校验请求时间与接收时间的偏差。调用方系统时钟应保持同步,每次请求均应使用当前时间生成签名。请求重试时需重新生成 X-Sdk-DateAuthorization

常见错误

错误现象检查项
签名验证失败检查 AK/SK 是否配对,HTTP 方法、URL、查询参数、已签请求头和 body 是否与签名输入一致
路径签名不一致检查 CanonicalURI 是否以 / 结尾;实际请求 URL 不应因签名规范化而增加尾斜杠
查询参数签名不一致检查 RFC 3986 编码、空格 %20、空值等号和参数排序;签名后不得修改 query
请求头签名不一致检查 HostContent-TypeX-Sdk-Date 的名称、值和 SignedHeaders 顺序
body 摘要不一致检查签名与发送是否使用同一份 UTF-8 字节,是否发生再次序列化、换行变化或编码变化
UNSIGNED-PAYLOAD 验签失败检查接口是否支持该方式,请求头名称和值是否正确,并确认该请求头已参与签名
请求时间错误检查系统时钟、UTC 格式以及是否复用了旧的 X-Sdk-DateAuthorization
body 超过限制AK/SK 认证仅支持 12M 以内的 body;超过限制时按照能力 API 文档使用 Token 认证