We have a case where we use presigned S3 urls as the src for image tags. These urls are valid for 5 minutes.
Our API returns a url for each available image size.
The frontend gets a list of user profiles which includes two profile photo urls for each profile, a url for a thumbnail and a url for a large view of the photo. All urls are valid for 5 minutes. The frontend caches the urls and displays the list of profiles. When a user clicks on a profile photo we display the larger version of the profile photo.
The problem is that it might be more than 5 minutes when a user clicks on a thumbnail so when the frontend displays the larger version of the profile photo the url for that image has already expired so we can't display it.
How to solve this problem?
One option is to use a hidden image tag for the larger image and make it visible when the user clicks or hovers over it. Because it's hidden, the browser will download it when the page is first rendered. The problem is that the list of profiles can be 100 items long which means that a lot of images will be downloaded and most will probably not be clicked on.
Another option is the extend the expiry time of the url to 12 hours. While this works it doesn't help if the user leaves their browser open for longer.
Finally, we thought maybe we can fetch the image presigned url when the user clicks on the thumbnail.
Why do we set an expiry on the image urls? It is because a user can hide their profile and when hidden their profile photo should not be available for viewing. So we set the url expiry to 5 minutes and we do not serve a new url if the profile has since be hidden.
Any thoughts on other ways to solve this issue? I feel that this must be a common problem and therefore there must be acceptable solutions that frontend devs use.
Top comments (1)
We ended up extending the expiry to 12 hours. Although this does not completely resolve the problem and is a bit of a hack imho it may be good enough for our use case.
Alternatively, we expose our own API which returns a redirect to S3. This way we don't have large amounts of data flowing through our API and instead let S3 take this load plus we can manage access to the images. This problem with this approach is that the API will be public and so we can't limit access to only logged in users, that is, we cannot attach an auth token when the browser downloads the image for the image tag. We could use an auth cookie but my team doesn't have control over the frontend, that is another team, and that would be a big change.