You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter调用Amazon Product API遇InvalidSignatureException错误求助

解决Flutter调用Amazon Product API的InvalidSignatureException错误

针对你遇到的签名无效错误,结合提供的代码,这里列出关键问题和修复方案:

1. 修复API路径错误

searchItems方法中调用_post时传入的路径错误,SearchItems接口的正确路径应为/paapi5/searchitems,路径不匹配会直接导致签名验证失败:

Future<SearchItemsResponse> searchItems(
    String keywords, List<String> resources) async {
  final body = {
    "Keywords": keywords,
    "Resources": resources,
    "PartnerTag": this.partnerTag,
    "PartnerType": "Associates",
    "Marketplace": this.marketplace.name,
    "Operation": PaAPIOperation.SearchItems.name
  };
  // 修正路径为/paapi5/searchitems
  final response =
      await _post('/paapi5/searchitems', body, PaAPIOperation.SearchItems);
  return SearchItemsResponse.fromJson(response);
}

2. 移除不必要的请求头

_createHeaders方法中添加的content-encoding: amz-1.0并非Amazon PA API要求的头字段,多余的请求头会被纳入签名计算,导致服务器端验证不通过,建议移除:

var headers = {
  'host': this.host,
  'content-type': 'application/json; charset=utf-8',
  // 移除此行不必要的头
  // 'content-encoding': 'amz-1.0',
  'x-amz-date': _getTimeStamp(currentDateTime),
  'x-amz-target': 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.$operation',
};

3. 确保JSON序列化一致性

签名计算依赖请求body的JSON哈希值,要保证签名计算时的JSON字符串与实际请求的完全一致。建议复用同一序列化结果,避免差异导致哈希不匹配:

// 修改_post方法,提前序列化并复用JSON字符串
Future<dynamic> _post(
    String path, Map<String, dynamic> body, PaAPIOperation operation) async {
  String bodyJson = json.encode(body);
  var headers = _createHeaders(path, operation.name, body, bodyJson);
  var url = Uri.parse('https://$host$path');
  var response = await http.post(url, headers: headers, body: bodyJson);
  var responseBody = utf8.decode(response.bodyBytes);
  return jsonDecode(responseBody);
}

// 同步修改_createHeaders和_prepareCanonicalRequest方法
Map<String, String> _createHeaders(
    String path, String operation, Map<String, dynamic> body, String bodyJson) {
  final currentDateTime = DateTime.now().toUtc();
  var headers = {
    'host': this.host,
    'content-type': 'application/json; charset=utf-8',
    'x-amz-date': _getTimeStamp(currentDateTime),
    'x-amz-target': 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.$operation',
  };

  final signedHeaders =
      (headers.keys.toList()..sort()).map((s) => s.toLowerCase()).join(';');

  String canonicalURL = _prepareCanonicalRequest(path, headers, bodyJson);
  String stringToSign = _prepareStringToSign(canonicalURL, currentDateTime);
  String signature = _calculateSignature(stringToSign, currentDateTime);

  headers['Authorization'] =
      _buildAuthorizationString(signedHeaders, signature, currentDateTime);

  return headers;
}

String _prepareCanonicalRequest(
    String path, Map<String, String> headers, String bodyJson) {
  final signedHeaders =
      (headers.keys.toList()..sort()).map((s) => s.toLowerCase()).join(';');

  final canonicalHeaders = headers.keys
      .map((key) => '${key.toLowerCase()}:${headers[key]?.trim()}')
      .toList()
    ..sort();

  var payloadHash = sha256.convert(utf8.encode(bodyJson)).toString();

  final canonicalURL = [
    'POST',
    path,
    '',
    ...canonicalHeaders,
    '',
    signedHeaders,
    payloadHash,
  ].join('\n');

  return canonicalURL;
}

4. 验证基础配置正确性

  • 确认_getTimeStamp和_getDate输出的UTC时间格式完全符合要求(yyyyMMdd'T'HHmmss'Z'和yyyyMMdd),时间偏差过大也会导致签名失效。
  • 检查PaAPIMarketplace枚举中的region值是否正确,比如美国市场对应us-east-1,区域不匹配会导致签名计算的凭证部分错误。
  • 核对accessKey、secretKey是否正确,且IAM用户拥有调用ProductAdvertisingAPI的权限;partnerTag需与所选市场匹配。

若修复后仍有问题,可对比Amazon官方签名流程,逐行检查规范请求、待签名字符串、签名密钥的生成步骤是否符合要求。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:46:21