So I have an Android chat application where users can create profile photos. These photos are sent to my Node JS backend where I upload them to my AWS S3 bucket. I store the key to their image in my SQL database under an "image_path" column in the "user" table.
Now whenever a user accesses a chatroom full of multiple other users in the app, they should be able to see other users' profile photos. Currently, upon joining a chatroom, a list of all users and their "image_path" is returned to the client. I am thinking about how to show the profile images to the user in an effective manner without violating best security practices.
The first solution I am thinking of is the following:
- Make S3 bucket read-public
- Client can now directly access other users' profile pictures via a "
bucket-name.s3.amazonaws.com/image_path" request.
My concern with this method is that S3 displays the following warning, which makes me think something is egregiously wrong with this approach:
You have provided public access to this bucket. We highly recommend that you never grant any kind of public access to your S3 bucket.
The second solution I am thinking of:
- When retrieving users in a chatroom, iterate through each user, create a pre-signed URL from each user's "
image_path" that expires after X time, and return that to the client instead
There are some problems I see with this. First, what if the user stays in the chat room for a period of time longer than the pre-signed url's expiry time? Implementing refresh logic for this sounds like a headache. Furthermore, generating all the pre-signed URLs seems like it'll supposedly take a long time in the backend.
Which of these two methods are recommended? Is there any other option I should consider?
UPDATE: So currently I am currently resorting to the first method and it is working fine - however, still want to know what the best practice is. I have thought of another method, and that is securing AWS credentials in my client and then using those credentials to retrieve the user object, while making the bucket private. However, this introduces the issue of storing additional credentials client-side which adds security issues, but I'm wondering if this is a viable option as well.