Aze*_*pas 2 php request signature amazon-web-services
我已经被这个问题困了两天了。我编写了一个 Python 脚本,它向 AWS Pinpoint 服务发出 PUT 请求。与许多其他 AWS 服务一样,Pinpoint 需要对请求进行签名验证,我设法在 Python 中处理了这一点。
现在我正在尝试将我的脚本翻译成 Symfony 的 PHP 服务。当我向 AWS pinpoint 运行我的第一个请求时,我得到以下信息:
我们计算的请求签名与您提供的签名不匹配。检查您的 AWS 秘密访问密钥和签名方法。有关详细信息,请参阅服务文档。 此请求的规范字符串应该是\n'PUT\n/v1/apps/.../endpoints/...\n\ncontent-type:application/json\nhost:pinpoint.eu-west-1。 amazonaws.com\nx-amz-content-sha256:de98d86577f0e1...655e6de27154af1c05ab34\nx-amz-date:20191226T151542Z\nx-amz-security-token:IQoJ-agent...放大/1.1.2 反应原生 aws-amplify/1.1.2 反应原生回调\n\ncontent-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token; x-amz-user-agent\n0240a9479d0a66d74eaae42dc...95247aaa800fcbe5cf2
String-to-Sign 应该是 'AWS4-HMAC-SHA256\n20191226T151542Z\n20191226/eu-west-1/mobiletargeting/aws4_request\nb2c451534fe370503ecf4068b4912803e20191226T151542Z
所以我已经检查过我的规范字符串是否错误,这与 AWS 要求的完全相同。String-to-Sign 与 Canonical String 哈希不同。
这是我的标题功能
public function create_headers($data,\DateTime $time,$canonical_uri,$method,$to_api=null)
{
$amz_date = $time->format('Ymd\THis\Z');
$date_stamp = $time->format('Ymd');
$payload_hash = hash('sha256',$data);#utf8_encode($data));
$canonical_querystring = "";
$canonical_headers = 'content-type:' . $this->content_type . '\n' . 'host:' . $this->host . '\n' . 'x-amz-content-sha256:' . $payload_hash . '\n' . 'x-amz-date:' . $amz_date . '\n' . 'x-amz-security-token:' . $this->security_token . '\n' . 'x-amz-user-agent:aws-amplify/1.1.2 react-native aws-amplify/1.1.2 react-native callback' . '\n';
$signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent';
$canonical_request = $method . '\n' . $canonical_uri . '\n' . $canonical_querystring . '\n' . $canonical_headers . '\n' . $signed_headers . '\n' . $payload_hash;
echo '<br><br>';
print_r(str_replace('\n','<br>',$canonical_request));
#var_dump($canonical_request);
$algorithm = 'AWS4-HMAC-SHA256';
$credential_scope = "{$date_stamp}/{$this->region}/{$this->service}/aws4_request";
#$date_stamp . '/' . $this->region . '/' . $this->service . '/' . 'aws4_request';
#$credential_scope = $this->createScope($date_stamp,$this->region,$this->service);
echo '<br><br>';
#$string_to_sign = $algorithm . '\n' . $amz_date . '\n' . $credential_scope . '\n' . hash('sha256', utf8_encode($canonical_request));
$hash = hash('sha256', $canonical_request);
$string_to_sign = "AWS4-HMAC-SHA256\n{$amz_date}\n{$credential_scope}\n{$hash}";
print_r(str_replace('\n','<br>',$string_to_sign));
echo '<br><br>';
$signing_key = $this->get_signature_key($this->secret_key,$date_stamp,$this->region,$this->service);
$signature = hash_hmac('sha256',$string_to_sign,$signing_key);
$authorization_header = $algorithm . ' ' . 'Credential=' . $this->access_key . '/' . $credential_scope . ', ' . 'SignedHeaders=' . $signed_headers . ', ' . 'Signature=' . $signature;
$headers = array(
'host'=> $this->host,
'content-type'=> $this->content_type,
'x-amz-user-agent'=> 'aws-amplify/1.1.2 react-native aws-amplify/1.1.2 react-native callback',
'x-amz-content-sha256'=> $payload_hash,
'x-amz-security-token'=> $this->security_token,
'x-amz-date'=> $amz_date,
'authorization'=> $authorization_header
);
$this->s->headers = $headers;
return $headers;
}
Run Code Online (Sandbox Code Playgroud)
几天来我一直在寻找我的错误,但我想我需要一个有新眼光的人......
谢谢!
经过数小时的自我质疑,我终于找到了为什么会出现该错误的原因。
在 PHP 中 "\n" 和 '\n' 没有相同的含义。
"\n" 是一个真正的换行符 -这就是 AWS 所要求的。
'\n' 是由 \ 和 n 个字符组成的字符串。
不过,AWS API 仍然很糟糕。
| 归档时间: |
|
| 查看次数: |
1014 次 |
| 最近记录: |