Bash/Shell 签名 SDK 接入指南

功能说明

Bash/Shell 签名 SDK 用于为美图开放平台 API 请求生成 AuthorizationX-Sdk-Date 等签名请求头。SDK 负责签名,HTTP 请求由调用方使用 curl 发送。

当前版本:AIGCP-API-shell-sdk-1.0.1

环境要求

  • 使用 Bash 运行脚本,不支持使用 sh 代替。
  • 安装 curl 7.76.0 或更高版本。
  • 安装 opensslbase64cutsedsortodtrdate
  • 确保服务器系统时间准确。

可执行以下命令检查环境:

for command_name in bash curl openssl base64 cut sed sort od tr date; do
  command -v "$command_name" >/dev/null || printf 'Missing command: %s\n' "$command_name" >&2
done

下载与引入

下载 AIGCP-API-shell-sdk-1.0.1.zip

unzip AIGCP-API-shell-sdk-1.0.1.zip
cd bash

解压后使用以下两个文件:

  • signer.sh:签名实现;
  • demo.sh:基础调用示例。

在业务脚本中引入 signer.sh

source ./signer.sh

接口说明

SDK 提供全局函数 Sign

auth_value=$(Sign "$access_key" "$secret_key" "$url" "$method" "$headers" "$body")
参数说明
access_key应用的 AK。
secret_key与 AK 配对的 SK。
url最终请求 URL,包含路径和完整查询参数。
methodHTTP 方法,使用大写,如 GETPOST
headers以换行符分隔的 Name:Value 请求头字符串。
body实际发送的请求体;无请求体时传空字符串。

Sign 返回以换行符分隔的请求头字符串。第一行是 Authorization,其余行是参与签名的请求头。发送请求时,需要将每一行分别转换为一个 curl -H 参数。

POST 完整调用示例

以下示例调用正式同步任务接口 https://openapi.meitu.com/api/v1/sdk/sync/push。请求体包含 tasktask_typeinit_imagesparamssync_timeout 五个顶层字段,其中 params 必须是 JSON 字符串。

示例中的任务、图片、业务参数和 sync_timeout: 30 需要根据目标能力的 API 文档填写。脚本使用同一个 body 变量完成签名和发送,保证参与签名与实际发送的字节完全一致。

#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C

script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
source "$script_dir/signer.sh"

: "${AIGCP_ACCESS_KEY:?AIGCP_ACCESS_KEY is required}"
: "${AIGCP_SECRET_KEY:?AIGCP_SECRET_KEY is required}"

send_signed_request() {
  local method=$1
  local url=$2
  local body=$3
  shift 3

  local raw_headers=("$@")
  local headers
  local auth_value
  local header
  local curl_args

  headers=$(printf '%s\n' "${raw_headers[@]}")
  if ! auth_value=$(Sign "$AIGCP_ACCESS_KEY" "$AIGCP_SECRET_KEY" "$url" "$method" "$headers" "$body"); then
    printf 'Signing failed\n' >&2
    return 1
  fi

  curl_args=(
    --silent
    --show-error
    --fail-with-body
    --connect-timeout 5
    --max-time 60
    --request "$method"
  )
  while IFS= read -r header; do
    [[ -n $header ]] && curl_args+=(-H "$header")
  done <<< "$auth_value"
  [[ -z $body ]] || curl_args+=(--data-binary "$body")

  curl "${curl_args[@]}" "$url"
}

post_endpoint='https://openapi.meitu.com/api/v1/sdk/sync/push'
post_url="${post_endpoint}?"
post_body='{"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}'
post_headers=(
  "Content-Type:application/json"
  "Host:openapi.meitu.com"
)

send_signed_request 'POST' "$post_url" "$post_body" "${post_headers[@]}"

将脚本保存为 request.sh,与 signer.sh 放在同一目录,然后设置 AK/SK 并执行:

export AIGCP_ACCESS_KEY='<your-access-key>'
export AIGCP_SECRET_KEY='<your-secret-key>'
bash request.sh

GET 调用示例

/api/v1/sdk/sync/push 只支持 POST。调用其他 GET API 时,在上面的完整脚本中将最后一段 POST 调用替换为以下内容,并使用目标 API 文档提供的真实 URL 和查询参数:

get_url='https://openapi.meitu.com/api/v1/replace-with-get-path?task_id=replace-with-task-id'
get_body=''
get_headers=(
  "Host:openapi.meitu.com"
)

send_signed_request 'GET' "$get_url" "$get_body" "${get_headers[@]}"

注意事项

  • 当前 Shell SDK 1.0.1 要求 URL 中包含 ?。没有查询参数时,在 URL 末尾保留空 ?;存在查询参数时,传入完整 query。签名和发送必须使用同一个 URL。
  • HTTP 方法、URL、请求头和 body 必须在签名前确定,签名后不得修改。
  • JSON body 只生成一次,并将同一个字符串同时传给 Signcurl --data-binary
  • 请求头使用 Name:Value 格式,值前不要添加多余空格;多个请求头按名称小写后的升序排列。
  • 不要手动设置 X-Sdk-Date,由 SDK 自动生成。
  • 默认情况下 SDK 会对 body 计算 SHA-256。仅当目标 API 明确支持时,才添加 X-Sdk-Content-Sha256:UNSIGNED-PAYLOAD
  • SK 仅保存在服务端,不要放入前端或客户端代码。

常见错误

错误现象处理方法
验签失败或返回 401检查 AK/SK、HTTP 方法、完整 URL、URL 末尾的 ?、请求头顺序及 body 是否与签名时完全一致。
时间相关错误同步服务器系统时间,并删除手动设置的 X-Sdk-Date
查询参数验签失败在签名前生成最终 query,签名后不要追加、删除或重新编码参数。
curl 提示不支持 --fail-with-body升级到 cURL 7.76.0 或更高版本,或改用 --fail
提示命令不存在根据“环境要求”安装缺失的命令。
API 返回业务参数错误按目标能力 API 文档替换示例中的 task、图片、paramstask_typesync_timeout