API Key 签名认证

API Key 签名认证

API Key 使用 AWS Signature V4(HMAC-SHA256)签名算法进行身份验证,适用于服务端集成和高安全场景。


创建 API Key

  1. 登录 M-Doc,进入「设置 > API Key」页面
  2. 点击「创建密钥」
  3. 设置名称和过期时间(可选)
  4. 保存 Access Key IDSecret Access Key

Secret Key 仅在创建时显示一次,请妥善保存。

请求格式

API Key 认证需要在请求头中携带以下信息:

Authorization: AWS4-HMAC-SHA256 Credential=<access_key>/<date>/<region>/<service>/aws4_request, SignedHeaders=host;x-amz-date, Signature=<signature>
X-Amz-Date: 20260410T120000Z
x-amz-content-sha256: <payload_hash>

签名流程

1. 准备时间戳

const now = new Date()
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '')  // 20260410T120000Z
const dateStamp = amzDate.slice(0, 8)  // 20260410

2. 计算 Payload Hash

const payloadHash = crypto.createHash('sha256').update(body || '').digest('hex')

3. 构建 Canonical Request

<HTTP Method>\n
<URI>\n
<Query String>\n
host:<host>\n
x-amz-date:<amzDate>\n
\n
host;x-amz-date\n
<payload_hash>

4. 构建 String to Sign

AWS4-HMAC-SHA256\n
<amzDate>\n
<dateStamp>/<region>/<service>/aws4_request\n
SHA256(<canonical_request>)

5. 计算签名密钥

const kDate = hmac('AWS4' + secretKey, dateStamp)
const kRegion = hmac(kDate, region)
const kService = hmac(kRegion, service)
const kSigning = hmac(kService, 'aws4_request')

6. 计算最终签名

const signature = hmac(kSigning, stringToSign, 'hex')

完整示例(JavaScript)

import crypto from 'crypto'

function signRequest({ method, url, body, accessKey, secretKey }) {
  const now = new Date()
  const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '')
  const dateStamp = amzDate.slice(0, 8)
  const service = 'mdoc'
  const region = 'us-east-1'

  const payloadHash = crypto.createHash('sha256')
    .update(body || '').digest('hex')

  const parsedUrl = new URL(url)
  const canonicalRequest = [
    method,
    parsedUrl.pathname,
    '',
    `host:${parsedUrl.host}\nx-amz-date:${amzDate}\n`,
    'host;x-amz-date',
    payloadHash,
  ].join('\n')

  const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`
  const stringToSign = [
    'AWS4-HMAC-SHA256',
    amzDate,
    credentialScope,
    crypto.createHash('sha256').update(canonicalRequest).digest('hex'),
  ].join('\n')

  const hmacFn = (key, data) =>
    crypto.createHmac('sha256', key).update(data).digest()

  const kDate = hmacFn(`AWS4${secretKey}`, dateStamp)
  const kRegion = hmacFn(kDate, region)
  const kService = hmacFn(kRegion, service)
  const kSigning = hmacFn(kService, 'aws4_request')
  const signature = crypto.createHmac('sha256', kSigning)
    .update(stringToSign).digest('hex')

  return {
    'Authorization': `AWS4-HMAC-SHA256 Credential=${accessKey}/${credentialScope}, SignedHeaders=host;x-amz-date, Signature=${signature}`,
    'X-Amz-Date': amzDate,
    'x-amz-content-sha256': payloadHash,
  }
}

注意事项

URI 编码

必须遵循 RFC 3986 规范:

  • 保留字符(不编码):A-Z a-z 0-9 - _ . ~
  • 空格编码为 %20(不是 +

Payload 一致性

用于签名计算的请求体必须与实际发送的请求体完全相同。不要重新序列化 JSON。

时间窗口

签名的有效时间窗口默认为 15 分钟。请确保客户端与服务器时间同步。

与 PAT 的区别

特性 API Key PAT
安全性 高(签名验证) 中(Bearer Token)
实现复杂度 较高 简单
权限控制 全部权限 按 Scope 控制
适用场景 服务端集成 脚本/CI/AI 工具

API Key 认证不受 Scope 限制,自动拥有所有 OpenAPI 接口的访问权限。