5

I'm using Strapi with local upload provider.

Whenever I upload a file, it is stored under the "public/uploads" folder locally, which is public.

Meaning that anyone with the file id, could download it eg. http://strapi-admin:1337/uploads/image1_9a9bd50a5b.png

However, I would like to only allow:

  • downloads to autenticated users which have the role "consumer" to be able to download files through the strapi API.

What is the best way for doing this?

Should I modify the upload extension directly? or is it any workaround I can use to implement this?

I would still like to store files locally (not using AWS3 and other cloud providers)

Thanks

Cem Kaan
  • 2,086
  • 1
  • 24
  • 55
letimome
  • 906
  • 2
  • 9
  • 21

1 Answers1

0

The best way you can solve this is to create a collection e.g FileShare. The Collection table could be like this: uuid (UID), filename (TEXT), fileid (NUMBER), role(related to Roles table), user(relate to user-permission table), status (BOOLEAN).

Using this logic, you will have to create a new route for file upload, the code upload from respective controller, The code below will help:

    const validateUploadBody = require('strapi-plugin-upload/controllers/validation/upload');
                async create(ctx){
             let userData=ctx.state?.user; let requestData=ctx.request.body;
         const {
                    request: { body, files: { files } = {} },
                  } = ctx;
          let uploadedFiles = await strapi.plugins.upload.services.upload.upload({
                data: await validateUploadBody(body),
                files,
              });
     let datat={
                filename:uploadedFiles[0].name,
                fileid:uploadedFiles[0].id,
                status:true,
                uuid:"3456345678", // Generate random perhaps use moment().format("x")
                role:2 //it can be any role of your choice
                                    }
  let updateLibrary= await strapi.query('file-shares').create(datat); 
        
        }

Ensure to use the uuid as the download enpoint from your frontend e.g https://example.com/file/2343567. Don't expose your media library url.

Then create a controller that will look for the file from FileShare table, check necessary permission for the user then download the file.

ziggybaba
  • 250
  • 3
  • 4