How to serve private images (any backend framework) but particularly NestJS
this is not necessary to anything im currently working on but just curious to know, since i tried this before in firebase and failed miserably, im wordering if a dedicated backend can solve this,
while i know how to serve public assests in a public uploads folder, i am wondering how do we control the access of these images to the owner,
let say we have a get posts api endpoint the get posts will obviously use the token to check the request and return the posts array among the attributes will be the image url, that images url is public and even if the post is private once the url is leaked there is no stopping any user from copy pasting that url in the browser and see the image and they have to be like that from my research so the <img> element can render the image
i've found that i can create a url that will expire in a matter of 2 minutes, but im not convinced about that method, any ideas how to approach this?
29 Replies
so, what you're trying to do is to prevent hotlinking?
that is, someone using your image somewhere else?
oh, i misread it
if a post is private, then you have to validate all post images by url, and check if these are in a private post or not
how you do that? depends on what you have
then you check if the user xyz has access to the post
if the user has, send the image
if not, send either a 403 or 404 error, depending on what you need
yes that will only control if i send the url or not, but no further checks , if i have the url regardless if im the only one allowed to see it or not i can copy paset it and see it
i need a solution so the url itself is secure
meaning i cant just copy paste the url as a nobody
well, the best and worst solution for it is to shove the images as base64 into the html
which is from my understanding its not something we are supposed to do since <img> element needs a public url to render the image
i see, so that will always bind us to the backend serving images no potential cdn's
you can have your own "cdn"
it will have to do all the validation work i said before
or the url invalidation system you have
a token and that token expires in 2 minutes
but that is not very cdn friendly too
well more like the url itself expires
and i have no idea about the read write impact of that method, it does sound like a lot of unnecessary changes just in the name of privacy
if you can do that, that's better
NOTHING IS UNNECESSARY IN THE NAME OF PRIVACY
if you can go further (without any harm or causing issues), do it
if the private images can't be cached by a cdn, well, fucking take it in the chin
so im looking at the discord scenario, if there is channel set to private obviously only allowed users can see the channel therefore the images posted there, but if someone authorised to go the channel, copy pastes the image sent in a private channel to a public or anywhere than anyone can see the image because the image url is public
then there is the google drive example that does not provide public urls, you cannot leak your own private images, and thats what im trying to achieve
discord controls it with a token
But i can open images in the browser and i even see the image in incognito mode
again, the access is controlled by a token
How so
it expires in 24 hours
So the url is tokenized
no, it has a parameter added
"tokenized" means something totally different
So leaking the url means leaking the part that authorizes the access
With it
But it expires so you need to renew the token and since unauthorized users can't generate new tokens it just blocks their request to see the image
that's kinda where im going, but not all the way
is this all custom code?
sorry, about what?
what you're doing
is it all custom code?
oh im just curious about protecting served images, my uses cases dont need this level of secrecy, but i was wondering how would i go about it if i needed that level of privacy, for example an app for storing your personal images or google drive for that matter
figuratively, there's a million ways to go about it
in my case i will protect the posts with access controls and hold the user accountable for leaking the urls, best i can do is make urls invalide after some time
also thank you so much for sharing this discussion with me 🙏
this and not even listing posts that are private for users that don't have access to those
but that should be obvious
yea the user will chose the visibility setting for each individual post so there will a lot of cases to check for
will the images and stuff be automatically moved to a cdn?
for now that is too early to even consider a cdn, so backend does it all for now
for now, that is the best option
Chiming in that you can set as background image too , it’s not fail proof but at least the user can’t just right click and get the url. Most average users won’t know how to get the image when it’s a bg image. And using base 64 as epic mentioned is another layer to help. You could also block right click on the <img> although that’s not great practice either . Basically if it’s accessible on the internet by anyone there’s no foolproof way to keep it totally private . The person with access could also screenshot too if they really wanted to share the image.
there's something crazy you can do
draw the image using a canvas
just send a lump of js data and render an image from it