Authenticated image download

Hi, I would like to implement a feature in OpenSaaS/WASP where users can publish some posts with images, but these posts should only be available to authenticated users (images shouldn't be public). I was thinking of using a WASP api, but then I cannot load images in React with a simple <img src="..."> tag. What would be your suggestion for implementing authenticated image download? This could probably be a nice default feature for opensaas. Thanks in advance!
7 Replies
kapa.ai
kapa.ai3w ago
Hi @Ramon. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To implement authenticated image download in Wasp, you can consider the following approach: 1. Storing Images: As per the discussion (https://discord.com/channels/686873244791210014/1210568665347526757) on Discord, it's recommended to store user-uploaded files on services like S3 or Azure Blob, as servers on most cloud providers are ephemeral and you can't count on data on disk being permanent. 2. Access Control: Currently, Wasp doesn't provide a built-in way to handle access control. However, you can add a role field to the User entity and check the value of that role in your queries/actions to decide if they should be able to execute that query/action or not. If they are not allowed, you can throw an HttpError 403. This was suggested in a support thread (https://discord.com/channels/686873244791210014/1211733266235916358) on Discord. 3. Serving Images: For serving images, you can create an API endpoint that checks if the user is authenticated and then serves the image. However, as you mentioned, this won't work with a simple <img src="..."> tag in React. One workaround could be to fetch the image as a Blob using the Fetch API, create an object URL for the Blob, and then set this URL as the src for your image. This way, you can include authentication in your fetch request. Please note that these are just suggestions and might need to be adjusted based on your specific use case. Also, as per the Github issue (https://github.com/wasp-lang/wasp/issues/494), Wasp currently doesn't support serving or uploading dynamic binary assets, but it's a feature that should be supported in the future. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Ramon, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
KC
KC2w ago
@Ramon I would recommend returning a pre-signed URL from S3 with a short TTL. If you want some inspiration, the openSaaS project has this implementation to upload files — https://docs.opensaas.sh/guides/file-uploading/. You can do something similar to view the files as well. Official docs: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html
OpenSaaS.sh
File Uploading
Open SaaS is a free, open-source, full-stack SaaS starter kit for React + NodeJS.
Sharing objects with presigned URLs - Amazon Simple Storage Service
Describes how to set up your objects so that you can share them with others by creating a presigned URL to download the objects.
KC
KC2w ago
Another option could be to proxy stream the media from your server instead of a URL.
martinsos
martinsos2w ago
Yup, that is it, what @KC linked to! That is the best way to handle it, via S3 + presigned URLs. And if you want to show them only to authenticated users, you can check in your Wasp Query/Action, when generating those links, that user is authenticated and is allowed to see the image.
Ramon
Ramon2w ago
Thanks, for my first version I'm using Multer instead of AWS S3, although my plan is to migrate to S3 as soon as the first users join. Do you know how to return these files from the server?
MEE6
MEE62w ago
Wohooo @Ramon, you just became a Waspeteer level 2!
martinsos
martinsos2w ago
I see now that our example doesn't show how to actually store the files on the disk. You would want to write them in some location on the disk (so write them), and then either expose that location completely so anybody can access it (via express route, you would likely set this up on serverSetup), or you could add another Wasp api that will return a file but will for example check taht user is authenticated, file belongs to user (if you have such knowl.edge you will want to store that in the database), ... . And then you would return file via response, prpobably in multiple pieces. Beyond basic guidelines, all this is not Wasp specific, you can google on how to do this in node and it will work!
Want results from more Discord servers?
Add your server