Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS S3 implementation for serving private files

Use case: We are developing a web application and the client has requested us to use AWS S3 to store the images. In the application, Everyone will have their own account and would upload their own images, some of the uploaded images will be public.

According to my understanding we can achieve this by using pre-singed URLs, to upload the images. But the problem that I am facing is, how to restrict access to the images to the other users.

like image 995
rava_avis Avatar asked Jan 30 '23 06:01

rava_avis


1 Answers

There are two basic ways to use Amazon S3:

  • Use it purely as a storage medium, only accessed by your application, or
  • Use it to serve content directly to end-users

In the first case, only your application has access to the data/files stored in S3. It must retrieve the content and serve it to users. This is a traditional approach for web servers.

In the second case, you can generate HTML pages that contain references to files stored in S3. For example, if an image appears within a web page, the src= parameter would point to an Amazon S3 URL. The file is then served from S3 without going via your web server.

This can be enhanced by using Pre-Signed URLs, which are time-limited URLs that provide access to private content stored in Amazon S3. It works like this:

  • The files are stored in S3 and are kept private (meaning no access permitted)
  • Your application is fully responsible for determining which users can access which files
  • When the application wishes to grant access to a user (eg they might want to view their own photos), it generates a Pre-Signed URL and includes this in the HTML page
  • When the user's web browser uses the Pre-Signed URL to access content
  • Amazon S3 receives the request, verifies the signature and timestamp on the Pre-Signed URL and, if approved, provides the file in response to the request

A Pre-Signed URL consists of:

  • A reference to the object requested
  • The Access Key associated with an IAM (Identity and Access Management) entity that has permission to access the object -- for example, you could create an IAM User that has the necessary permissions, and then provide these access credentials to your application
  • An expiry timestamp until which the Pre-Signed URL is valid
  • A cryptographically-calculated signature that verifies that the Pre-Signed URL was created by the entity that owns the Access Key (effectively, it verifies the password and hashes the above information)

The Pre-Signed URL can be created in just a couple of lines of code and does not require a call to the AWS API.

Bottom line: Keep all images private. Your application confirms each user's right to access the images on-the-fly, then generates URLs to grant time-limited access.

like image 198
John Rotenstein Avatar answered Jan 31 '23 19:01

John Rotenstein