Javascript casl中的项目级权限

Javascript casl中的项目级权限,javascript,reactjs,casl,Javascript,Reactjs,Casl,在我的情况下,权限不是基于角色的,而且在登录后也不会有一个我可以放置的中心权限对象。权限发生在项目级别。权限发生在项目级别,我的意思是说,如果我有一个todos对象,它大约有4个项目,那么每个项目可能有不同的权限,如下所示 const todos = { data: [ { id: 1, title: "Todo 1", sub: "Let's start!", permissions: [

在我的情况下,权限不是基于角色的,而且在登录后也不会有一个我可以放置的中心权限对象。权限发生在项目级别。权限发生在项目级别,我的意思是说,如果我有一个todos对象,它大约有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处理权限

这就是我在做的

ability.js

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

export default new Ability([
  {
    action: "read",
    subject: "todo"
  },
  {
    action: "delete",
    subject: "todo"
  }
]);
can.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;
从“React”导入React;
从“@casl/Ability”导入{Ability}”;
从“/Can”导入{AbilityContext,Can};
常数todos={
数据:[
{
id:1,
标题:“待办事项1”,
潜艇:“我们开始吧!”,
权限:[
{
行动:“阅读”,
主题:“待办事项”
},
{
行动:“删除”,
主题:“待办事项”
}
],
__typename:“Todo”
},
{id:2,标题:“Todo 2”,sub:“让我们开始2!”,\uu typename:“Todo”},
{
id:3,
标题:“待办事项3”,
潜艇:“让我们开始3号!”,
权限:[
{
行动:“阅读”,
主题:“待办事项”
}
],
__typename:“Todo”
},
{id:4,标题:“Todo 4”,sub:“让我们开始4!”,\uu typename:“Todo”}
]
};
const权限=()=>{
常量ability=React.useContext(AbilityContext);
返回(
基于权限的系统
{todos.data.map((todo)=>(
{todo.title}
{todo.sub}
删除
))}
);
};
导出默认权限;
我还创建了一个沙箱


对于这种情况,当您拥有嵌入实体的权限时,您不需要CASL。你可以使用它,但它不会带来任何好处。为什么?

  • 您复制
    主题
    待办事项
    ,以响应数组中的每个待办事项。您知道您请求了
    Todo
    ,甚至
    GraphQL
    s
    \uu typename
    属性都会告诉您这一点
  • 它需要为每个主题类型创建一个
    Ability
    实例(在本例中为
    Todo
    ),迭代所有Todo,根据id生成一个条件对象(因此我们可以稍后检查
    Ability.can('read',Todo)
  • 所有这些都是无用的,带来了额外的复杂性,根本没有好处

    更好的案例结构如下:

    权限:{
    坎瑞德:没错,
    坎德莱特:没错
    }
    
    因此,您可以轻松检查UI上的权限-
    todo.permissions.canRead