I'm using a Django backend along with a React web app and a React Native mobile app to store files in S3. However, I want to make sure these files aren't publicly accessible. Specifically, I don't want someone to be able to copy the S3 URL and access the files directly in their browser. My goal is to ensure that: 1) S3 files can only be accessed through my web and mobile apps, and 2) direct access via raw S3 URLs should not be possible. How can I implement this for both my web and mobile applications?
4 Answers
You're on the right track! To keep files safe, you need to verify that users are authorized to access them—think of checking for a valid token. Just make sure not to pass that token in the URL, like through query parameters, because then anyone with the link can use it. Instead, include the token in the request headers. This way, if someone tries to open the link without the token, they won't be able to get the file. For server-side processing, using a Lambda function to pull files from S3 for authenticated users is effective too! You could also integrate CloudFront to manage access before delivering the content.
How you handle access will depend on your app’s authentication. Implementing AWS Cognito identity pools can be a solid option for managing user authentication and authorization effectively.
Check out CloudFront's Origin Access Control. It’s a neat way to restrict access to your S3 content, ensuring only authorized users can get to the files. You can read more about it in the AWS documentation.
To keep your S3 files private, only allow your server, container, or Lambda function access to them. Then, when an authenticated user needs to access a file, generate a pre-signed URL. This way, they can use it while ensuring only your apps can get what they need without exposing the files directly to the web.

So if I share that presigned URL, couldn’t anyone use it until it expires? That doesn’t really prevent direct access, right?