绑带-限制用户仅获取与他有关的数据

时间:2018-11-12 15:42:16

标签: koa strapi

通常,登录的用户会获得内容类型的所有条目。

我创建了一个“摘要”内容类型(_id,name,content,users<<->>snippets)

<<->>表示“具有并属于许多”关系。

我创建了一些测试用户并提出了一个请求: curl -H 'Authorization: Bearer eyJ...' http://localhost:1337/snippets/

主要问题:经过身份验证的用户应只看到分配给他的条目。相反,登录的用户会获取所有摘要,这很糟糕。

如何修改fetchAll(ctx.query);查询以将其考虑在内,以便在fetchAll(ctx.state.user.id);-route-> /方法中执行类似find的操作?

基本查找方法在这里:

find: async (ctx) => {

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

子问题:当我进行Bearer-Token身份验证时,stradi甚至不知道登录了哪个用户?

3 个答案:

答案 0 :(得分:3)

您可以在代码片段配置下设置/ snippets / me路由。

该路由可以调用Snippets.me控制器方法,该方法将检查用户,然后根据用户查询代码段。

所以在api/snippet/config/routes.json中会出现类似这样的内容:

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

然后在控制器(api/snippet/controllers/Snippet.js)中,您可以执行以下操作:

  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);
  },

然后,您将向经过身份验证的用户授予me路由权限,而不是整个代码段路由权限。

答案 1 :(得分:2)

以上是正确的,但新版本的bandi除外。使用find而不是fetch:)

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

Strapi v3.0.0-beta.20

答案 2 :(得分:2)

可能会在限制登录用户的情况下扩展控制器中findfindOne使用的查询。在这种情况下,您可能还需要调整count端点以使其一致。

这将导致:

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

根据您对控制器和服务的使用,可以通过改编service methods来实现相同的目的。

这种解决方案可与GraphQL插件一起使用。