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

Presigned S3 url valid after expiry time


From the SDK documentation (link: https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html#_createPresignedRequest) the $expires parameter should denote the time at which the URL should expire.

So if I specified 2 minutes as an expiration time, after 2 minutes the URL should be invalid. My code looks like this

<?php
$s3 = $this->cloudProvider->getClient(); // S3 client

$cmd = $s3->getCommand(
    'GetObject',
    [
        'Bucket' => $this->getSdkBucket(), // Bucket name
        'Key' => "$s3Name",
    ]
);

$urlReq = $s3->createPresignedRequest($cmd, $expirationTime); // $expirationTime is a Unix timestamp

And I get the url that has the correct expiry time (in my case the client wanted it to be the session expiry time, and session time is 4 hours)

  X-Amz-Content-Sha256=UNSIGNED-PAYLOAD
  &X-Amz-Security-Token=long_string_goes_here
  &X-Amz-Algorithm=AWS4-HMAC-SHA256
  &X-Amz-Credential=another_string_goes_here
  &X-Amz-Date=20200907T110127Z
  &X-Amz-SignedHeaders=host
  &X-Amz-Expires=14400 // This decreases depending on how long the user is logged in - max 4hrs
  &X-Amz-Signature=another_string_here

The problem is that this url will be valid after 4 hours.

From what I've read in this answer about expiry time (https://stackoverflow.com/a/57792699/629127), the URL will be valid from 6 hours up to 7 days, depending on the credentials used to generate it.

And I'm using the IAM credentials (ECS provider).

So does this means that no matter what value I put in the expiry variable, I won't be able to make the link valid for that time period?


Solution

  • The expiration time is checked by S3 and if the browser or a proxy (if you are using CloudFront, for example) has the file cached then the request won't reach S3. If it is cached in the browser then don't worry, that means the same user can access the URL after expiration only.

    You can use the browser devtools to check for this. On the network tab, find the request to the signed URL and you can see if it was returned from the cache (from memory/disk cache).