skip to Main Content

Stack is:

  1. Angular
  2. Laravel
  3. S3
  4. nginx

I’m using S3 to store confidential resources of my users. Bucket access is set to private which means I can access files either by creating temporary (signed, dynamic) links or by using Storage::disk('s3')->get('path/to/resource') method and returning an actual file as a response.

I’m looking for a way to cache resources in user’s browser. I have tried to set cache headers to resource response directly on AWS, but since I’m creating temporary urls, they are dynamic and cache is not working in that case.

Any suggestion is highly appreciated.

EDIT: One thing that makes the whole problem even more complex is that security of resources should be intact. It means that I need a way to cache resources, but in the same time I must prevent users from copy-pasting links and using them outside of the app (sharing with others via direct links).

Temporary links in terms of security are still not an ideal solution, since they can be shared (and accessed multiple times) within the period of time they are valid for (in my case it’s 30 seconds).

2

Answers


  1. Caching will work as-is (based on Cache-Control, et al.) as long as the URL stays the same. So, if your application uses the same signed URL for awhile, you’ll be fine.

    The problem comes when you want to update an expiration date or something. This of course has different querystring parameters, and is effectively a different URL. You need a different caching key, but the browser has no concept of this by default.

    If it is acceptable for your security, you can create a Service Worker which uses just the base URL (without querystring) as the cache key. Then, future requests for the same object on the bucket will be able to used the cached response, regardless of other URL parameters.

    I must prevent users from copy-pasting links and using them outside of the app (sharing with others via direct links).

    This part of your requirement is impossible, and unrelated to caching. Once that URL is signed, it can be used by others.

    Login or Signup to reply.
  2. You have just add one parameter in your code.

    'ResponseCacheControl' => 'no-store'
    
    Storage::disk('s3')->getAwsTemporaryUrl(Storage::disk('s3')->getDriver()->getAdapter(), trim($mNameS3), CarbonCarbon::now()->addMinutes(config('app.aws_bucket_temp_url_time')), ['ResponseCacheControl' => 'no-store']);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search