Laravel调用AWS SES V2 DeleteSuppressedDestination API签名错误求助
AWS SES V2 DeleteSuppressedDestination 签名不匹配问题分析与解决
1. URI未对邮箱地址进行URL编码
Delete请求的URI包含邮箱地址(如/v2/email/suppression/addresses/user@example.com),其中@、.等特殊字符需进行URL编码。当前代码直接拼接邮箱地址,导致签名计算时的canonical URI与实际请求的URI不一致,这是签名不匹配的核心原因之一。
解决方法:
对邮箱地址使用rawurlencode()编码后再拼接URI:
$uri = '/v2/email/suppression/addresses/' . rawurlencode($email);
2. 签名计算未正确处理二进制密钥
生成最终签名时,$kSigning是二进制格式的密钥,但当前调用hash_hmac未指定返回二进制结果,PHP会将二进制密钥当作字符串处理,导致计算出的签名错误。
解决方法:
修改签名生成逻辑,计算$signature时返回二进制结果,再通过bin2hex()转换为十六进制字符串:
$signature = bin2hex(hash_hmac('sha256', $stringToSign, $kSigning, true));
3. 多余的Content-Type header及未捕获的自动添加headers
当前代码返回的Content-Type: application/x-www-form-urlencoded对无请求体的DELETE请求完全多余。此外,如果HTTP客户端(如Guzzle)自动添加了Content-Length: 0等headers,但这些headers未包含在签名计算的canonicalHeaders和signedHeaders中,也会导致签名不匹配。
解决方法:
- 删除多余的
Content-Typeheader:return [ 'Authorization' => $authorizationHeader, 'x-amz-date' => $amzDate, ]; - 检查客户端是否自动添加其他headers,若存在则补充到签名计算中。例如存在
Content-Length:0时,修改如下:$canonicalHeaders = "content-length:0\nhost:$host\nx-amz-date:$amzDate\n"; $signedHeaders = 'content-length;host;x-amz-date';
4. 验证canonicalRequest正确性
打印生成的$canonicalRequest和$stringToSign,与AWS签名规则手动计算结果对比,重点核对:
- HTTP方法是否为大写
DELETE - canonical URI是否与编码后的实际URI完全一致
- canonical headers是否按字母顺序排序
- payload hash是否为空字符串的SHA256值:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
内容的提问来源于stack exchange,提问作者Himanshu Joshi
相关产品推荐
相关产品推荐

