2

在我的情况下,权限不是基于角色的,也不会有一个我可以在登录后放置的中央权限对象。权限发生在项目级别。通过在项目级别上发生许可,我的意思是说,如果我有一个大约有 4 个项目的待办事项对象,那么每个项目可能会获得不同的许可,如下所示

const todos = {
  data: [
    {
      id: 1,
      title: "Todo 1",
      sub: "Let's start!",
      permissions: [
        {
          action: "read",
          subject: "todo"
        },
        {
          action: "delete",
          subject: "todo"
        }
      ],
      __typename: "Todo"
    },
    { id: 2, title: "Todo 2", sub: "Let's start 2!", __typename: "Todo" },
    {
      id: 3,
      title: "Todo 3",
      sub: "Let's start 3!",
      permissions: [
        {
          action: "read",
          subject: "todo"
        }
      ],
      __typename: "Todo"
    },
    { id: 4, title: "Todo 4", sub: "Let's start 4!", __typename: "Todo" }
  ]
};

对于这种情况,我如何使用 casl 处理权限?

这就是我正在做的

能力.js

import { Ability } from "@casl/ability";

export default new Ability([
  {
    action: "read",
    subject: "todo"
  },
  {
    action: "delete",
    subject: "todo"
  }
]);

可以.js

import { createContext } from "react";
import { createContextualCan } from "@casl/react";

export const AbilityContext = createContext();
export const Can = createContextualCan(AbilityContext.Consumer);

index.js

import React from "react";
import { Ability } from "@casl/ability";
import { AbilityContext, Can } from "./can";

const todos = {
  data: [
    {
      id: 1,
      title: "Todo 1",
      sub: "Let's start!",
      permissions: [
        {
          action: "read",
          subject: "todo"
        },
        {
          action: "delete",
          subject: "todo"
        }
      ],
      __typename: "Todo"
    },
    { id: 2, title: "Todo 2", sub: "Let's start 2!", __typename: "Todo" },
    {
      id: 3,
      title: "Todo 3",
      sub: "Let's start 3!",
      permissions: [
        {
          action: "read",
          subject: "todo"
        }
      ],
      __typename: "Todo"
    },
    { id: 4, title: "Todo 4", sub: "Let's start 4!", __typename: "Todo" }
  ]
};

const Permission = () => {
  const ability = React.useContext(AbilityContext);
  return (
    <>
      <h1>Permission Based System</h1>
      {todos.data.map((todo) => (
        <div key={todo.id}>
          <Can I="read" a="todo">
            <div style={{ display: "flex", alignItems: "center" }}>
              <div style={{ display: "flex", flexDirection: "column" }}>
                <h1 style={{ margin: 0 }}>{todo.title}</h1>
                <h3>{todo.sub}</h3>
              </div>
              <Can I="delete" a="todo">
                <span>Delete</span>
              </Can>
            </div>
          </Can>
        </div>
      ))}
    </>
  );
};

export default Permission;

我也创建了一个沙箱

https://codesandbox.io/s/mystifying-leaf-i968u?file=/src/permission/index.js:0-1472

4

1 回答 1

0

例如,当您将权限嵌入到实体中时,您不需要 CASL。你可以使用它,但它不会带来任何好处。为什么?

  1. 您无缘无故地重复subject Todo响应数组中的每个待办事项。你知道你要求Todo,甚至GraphQLs__typename财产告诉你这一点。
  2. 它需要为Ability每个主题类型创建一个实例(在本例中Todo),遍历所有待办事项,通过 id 生成条件对象(以便我们稍后检查ability.can('read', todo))。

所有这些都是无用的,带来了额外的复杂性,而且根本没有好处。

对于您的情况,更好的结构是:

permissions: {
  canRead: true,
  canDelete: true
}

因此,您可以轻松检查 UI 上的权限 -todo.permissions.canRead

于 2020-12-17T08:38:25.803 回答