Search code examples
koastrapi

strapi - restrict user to fetch only data related to him


Usually, a logged-in user gets all entries of a Content Type.

I created a "snippets" content type (_id,name,content,users<<->>snippets)

<<->> means "has and belongs to many" relation.

I created some test users and make a request: curl -H 'Authorization: Bearer eyJ...' http://localhost:1337/snippets/

Main Problem: an authenticated user should only see the entries assigned to him. Instead, a logged-in user gets all snippets, which is bad.

How is it possible to modify the fetchAll(ctx.query); query to take that into account so it does something like fetchAll(ctx.state.user.id); at the /-route->find-method ?

The basic find method is here:

find: async (ctx) => {

    if (ctx.query._q) {
      return strapi.services.snippet.search(ctx.query);
    } else {
      return strapi.services.snippet.fetchAll(ctx.query);
    }
},

Sub-Question: Does strapi even know which user is logged in when I do Bearer-Token Authentication ?


Solution

  • You could set up a /snippets/me route under the snippets config.

    That route could call the Snippets.me controller method which would check for the user then query snippets based on the user.

    So in api/snippet/config/routes.json there would be something like :

        {
          "method": "GET",
          "path": "/snippets/me",
          "handler": "Snippets.me",
          "config": {
            "policies": []
          }
        },
    

    Then in the controller (api/snippet/controllers/Snippet.js), you could do something like:

      me: async (ctx) => {
        const user = ctx.state.user;    
        if (!user) {
          return ctx.badRequest(null, [{ messages: [{ id: 'No authorization header was found' }] }]);
        }
    
        const data = await strapi.services.snippet.fetch({user:user.id});  
    
        if(!data){
          return ctx.notFound();
        }
    
        ctx.send(data);
      },
    

    Then you would give authenticated users permissions for the me route not for the overall snippets route.