strapi - restrict user to fetch only data related to him

前端 未结 3 886
执念已碎
执念已碎 2020-12-31 21:31

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

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

相关标签:
3条回答
  • 2020-12-31 22:13

    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.

    0 讨论(0)
  • 2020-12-31 22:28

    A possibility would be to extend the query used by find and findOne in the controllers with a restriction regarding the logged in user. In this case you might also want to adapt the count endpoint to be consistent.

    This would result in:

    withOwnerQuery: (ctx, ownerPath) => {
      const user = ctx.state.user;
      if (!user) {
        ctx.badRequest(null, [
          { messages: [{ id: "No authorization header was found" }] },
        ]);
        return null;
      }
      return { ...ctx.query, [ownerPath]: user.id };
    };
    
    find: async (ctx) => {
        ctx.query = withOwnerQuery(ctx, "owner.id");
        if (ctx.query._q) {
          return strapi.services.snippet.search(ctx.query);
        } else {
          return strapi.services.snippet.fetchAll(ctx.query);
        }
    },
    
    // analogous for for findOne
    

    Depending on your usage of controllers and services you could achieve the same thing via adapting the service methods.

    This kind of solution would work with the GraphQL plugin.

    0 讨论(0)
  • 2020-12-31 22:36

    The above is correct, except with newer versions of strapi. Use find and not fetch :)

    const data = await strapi.services.snippet.find({ user: user.id });
    

    Strapi v3.0.0-beta.20

    0 讨论(0)
提交回复
热议问题