Search code examples
phpamazon-web-servicesamazon-s3aws-php-sdk

How do I get a file from S3 with aws-sdk-php?


I want to get a AWS S3 url to be able to download a file from a browser but I keep getting this error

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<AWSAccessKeyId>xxxxxxxxxx</AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256 20230729T002138Z 20230729/us-west-1/s3/aws4_request faxxxxxxxxxxxeb2a</StringToSign>
<SignatureProvided>c6d5xxxxxxxxx3df9</SignatureProvided>
<StringToSignBytes>41 57 53 34 2d 35 65 62 32 61 66 35 66 66 30 64</StringToSignBytes>
<CanonicalRequest>GET //dummy.pdf X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIXX%2F729%2Fus-west-1%2Fs3%2Faws4_request&X-Amz-Date=20230729T002138Z&X-Amz-Expires=1200&X-Amz-SignedHeaders=host host:test-storage.s3.us-west-1.amazonaws.com host UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>47 45 54 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes>
<RequestId>EMXXXXXX032</RequestId>
<HostId>FcXXXXXXXXo=</HostId>
</Error>

This is my code:

$client = new S3Client([
    'version'     => 'latest',
    'region'      => 'us-west-1',
    'credentials' => [
        'key'    => 'xxxxxxx',
        'secret' => 'xxxxxxx',

    ],
]);

$cmd = $client->getCommand('GetObject', [
    'Bucket' => 'test-storage',
    'Key'    => 'dummy.pdf',
]);

$tmp          = $client->createPresignedRequest($cmd, '+20 minutes');
$presignedUrl = (string) $tmp->getUri();

This is what $presignedUrl looks like

https:\/\/test-storage.s3.us-west-1.amazonaws.com\/dummy.pdf?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKI0729%2Fus-west-1%2Fs3%2Faws4_request&X-Amz-Date=20230729T004906Z&X-Amz-SignedHeaders=host&X-Amz-Expires=1200&X-Amz-Signature=11111111534793c314b

Why am I getting this error and how do I fix it?

enter image description here


Solution

  • Usually this message stems from an incorrect or corrupted signature. How are you getting it from this code? If you do echo $presignedUrl; for ex when running from CLI and paste that in your browser. I am not sure if you intentionally trimmed the signature but it looks on the short side. Usually looks more like this:

    X-Amz-Signature=0115fcdcc121301ba9c44d14445aeb99e0a5a58383e28d3314c4c3a6d0d81d15%
    

    The fact that your slashes are escaped makes me wonder if there is something going on with your output.