React 应用程序中的 CASL 授权 "Can" 条件无效
CASL Authorisation in a React app "Can" conditions have no effect
我正在尝试在 React 应用程序中实现 CASL 授权,我认为我不太了解如何实现它。
标准的 Can 组件似乎可以与基本的 CRUD 操作一起使用,但我无法获得产生任何效果的条件。我想我错过了什么。
我目前的理论是我需要使用 TypeScript 而不是普通的 Javascript 来使整个事情正常进行。我目前不知道任何 TypeScript,我真的很想推进我的应用程序,而不是必须学习另一种语言。如果必须的话,我会学习 TypeScript,但我需要知道它是否值得这样做。下面是我到目前为止所构建内容的简化版本。
预期行为
我希望该应用程序显示此人可以读取和创建事物记录。他们还应该能够更新或删除特定的 Apple 记录。
预期输出:
我可以看看东西
我可以创造一个东西
我可以更新这个苹果
我可以删除这个苹果
实际行为
它忽略与条件有关的任何事情,并允许对所有内容进行创建、读取、更新和删除。
实际输出:
我可以看看东西
我可以创造一个东西
我可以更新任何东西
我可以删除任何东西
主应用程序
import "./styles.css";
import ThingManager from "../components/ThingManager";
import AbilityContextComponent from "../components/AbilityContextComponent";
export default function App() {
return (
<div className="App">
<AbilityContextComponent>
<ThingManager />
</AbilityContextComponent>
</div>
);
}
技能上下文组件
用于构建能力上下文并结束能力的生成
import React from "react";
import { AbilityContext } from "../src/Can";
import { defineAbility } from "@casl/ability";
class AbilityContextComponent extends React.Component {
render() {
const ability = defineAbility((can) => {
can("read", "thing");
can("create", "thing");
can("update", "thing", { userId: 3 });
can("delete", "thing", { userId: 3 });
});
return (
<AbilityContext.Provider value={ability}>
{this.props.children}
</AbilityContext.Provider>
);
}
}
export default AbilityContextComponent;
这里生成了Can组件
import { createContextualCan } from "@casl/react";
import React from "react";
export const AbilityContext = React.createContext();
export const Can = createContextualCan(AbilityContext.Consumer);
终于可以使用“事物”授权的组件
import React from "react";
import { Can } from "../src/Can";
class ThingManager extends React.Component {
render() {
const thing = {
Name: "Apple",
Description: "this is an Apple",
Colour: "Green",
UserId: 3
};
return (
<div>
<h3>Manage your things here</h3>
<Can I="read" a="thing">
<p>I can look at things</p>
</Can>
<Can I="create" a="thing">
<p>I can create a thing</p>
</Can>
<Can I="update" a="thing">
<p>I can update any thing</p>
</Can>
<Can I="delete" a="thing">
<p>I can delete any thing</p>
</Can>
<Can I="update" this={thing}>
<p>I can delete this {thing.Name}</p>
</Can>
<Can I="delete" this={thing}>
<p>I can delete any {thing.Name}</p>
</Can>
</div>
);
}
}
export default ThingManager;
我一直在寻找有关如何更改“主题”的信息,这是 CASL 对您尝试设置权限的事物的术语。在这种情况下,我称之为“东西”。
原来有很多方法可以检测主题类型。
通常它们都涉及告诉 Can 组件传入的 object 的主题是什么。
基本方法是在传递给“this”的 object 上调用函数 subject。
从“@casl/ability”导入主题,并像 subject("thing", apple)
Working version on CodeSandBox
import React from "react";
import { Can } from "../src/Can";
import { subject } from "@casl/ability";
class ThingManager extends React.Component {
render() {
const apple = {
Name: "Apple",
Description: "this is an Apple",
Colour: "Green",
UserId: 3
};
return (
<div>
<h3>Manage your things here</h3>
<Can I="read" a="thing">
<p>I can look at things</p>
</Can>
<Can I="create" a="thing">
<p>I can create a thing</p>
</Can>
<Can I="update" a="thing">
<p>I can update a thing</p>
</Can>
<Can I="delete" a="thing">
<p>I can delete a thing</p>
</Can>
<Can I="update" this={subject("thing", apple)}>
<p>I can delete this {apple.Name}</p>
</Can>
<Can I="delete" this={subject("thing", apple)}>
<p>I can delete any {apple.Name}</p>
</Can>
</div>
);
}
}
export default ThingManager;
我对 Can 工作原理的理解也有点错误。您会在工作示例中注意到“我可以更新一个东西”和“我可以删除一个东西”文本仍在显示。这是因为一般的“Can I update a”和“Can I delete a”类型的组件都会显示它们的 children 只要用户可以 update/delete 至少一件事情。它并不是说“此用户可以访问所有内容”。
我正在尝试在 React 应用程序中实现 CASL 授权,我认为我不太了解如何实现它。
标准的 Can 组件似乎可以与基本的 CRUD 操作一起使用,但我无法获得产生任何效果的条件。我想我错过了什么。
我目前的理论是我需要使用 TypeScript 而不是普通的 Javascript 来使整个事情正常进行。我目前不知道任何 TypeScript,我真的很想推进我的应用程序,而不是必须学习另一种语言。如果必须的话,我会学习 TypeScript,但我需要知道它是否值得这样做。下面是我到目前为止所构建内容的简化版本。
预期行为
我希望该应用程序显示此人可以读取和创建事物记录。他们还应该能够更新或删除特定的 Apple 记录。
预期输出:
我可以看看东西
我可以创造一个东西
我可以更新这个苹果
我可以删除这个苹果
实际行为
它忽略与条件有关的任何事情,并允许对所有内容进行创建、读取、更新和删除。
实际输出:
我可以看看东西
我可以创造一个东西
我可以更新任何东西
我可以删除任何东西
主应用程序
import "./styles.css";
import ThingManager from "../components/ThingManager";
import AbilityContextComponent from "../components/AbilityContextComponent";
export default function App() {
return (
<div className="App">
<AbilityContextComponent>
<ThingManager />
</AbilityContextComponent>
</div>
);
}
技能上下文组件 用于构建能力上下文并结束能力的生成
import React from "react";
import { AbilityContext } from "../src/Can";
import { defineAbility } from "@casl/ability";
class AbilityContextComponent extends React.Component {
render() {
const ability = defineAbility((can) => {
can("read", "thing");
can("create", "thing");
can("update", "thing", { userId: 3 });
can("delete", "thing", { userId: 3 });
});
return (
<AbilityContext.Provider value={ability}>
{this.props.children}
</AbilityContext.Provider>
);
}
}
export default AbilityContextComponent;
这里生成了Can组件
import { createContextualCan } from "@casl/react";
import React from "react";
export const AbilityContext = React.createContext();
export const Can = createContextualCan(AbilityContext.Consumer);
终于可以使用“事物”授权的组件
import React from "react";
import { Can } from "../src/Can";
class ThingManager extends React.Component {
render() {
const thing = {
Name: "Apple",
Description: "this is an Apple",
Colour: "Green",
UserId: 3
};
return (
<div>
<h3>Manage your things here</h3>
<Can I="read" a="thing">
<p>I can look at things</p>
</Can>
<Can I="create" a="thing">
<p>I can create a thing</p>
</Can>
<Can I="update" a="thing">
<p>I can update any thing</p>
</Can>
<Can I="delete" a="thing">
<p>I can delete any thing</p>
</Can>
<Can I="update" this={thing}>
<p>I can delete this {thing.Name}</p>
</Can>
<Can I="delete" this={thing}>
<p>I can delete any {thing.Name}</p>
</Can>
</div>
);
}
}
export default ThingManager;
我一直在寻找有关如何更改“主题”的信息,这是 CASL 对您尝试设置权限的事物的术语。在这种情况下,我称之为“东西”。
原来有很多方法可以检测主题类型。
通常它们都涉及告诉 Can 组件传入的 object 的主题是什么。
基本方法是在传递给“this”的 object 上调用函数 subject。
从“@casl/ability”导入主题,并像 subject("thing", apple)
Working version on CodeSandBox
import React from "react";
import { Can } from "../src/Can";
import { subject } from "@casl/ability";
class ThingManager extends React.Component {
render() {
const apple = {
Name: "Apple",
Description: "this is an Apple",
Colour: "Green",
UserId: 3
};
return (
<div>
<h3>Manage your things here</h3>
<Can I="read" a="thing">
<p>I can look at things</p>
</Can>
<Can I="create" a="thing">
<p>I can create a thing</p>
</Can>
<Can I="update" a="thing">
<p>I can update a thing</p>
</Can>
<Can I="delete" a="thing">
<p>I can delete a thing</p>
</Can>
<Can I="update" this={subject("thing", apple)}>
<p>I can delete this {apple.Name}</p>
</Can>
<Can I="delete" this={subject("thing", apple)}>
<p>I can delete any {apple.Name}</p>
</Can>
</div>
);
}
}
export default ThingManager;
我对 Can 工作原理的理解也有点错误。您会在工作示例中注意到“我可以更新一个东西”和“我可以删除一个东西”文本仍在显示。这是因为一般的“Can I update a”和“Can I delete a”类型的组件都会显示它们的 children 只要用户可以 update/delete 至少一件事情。它并不是说“此用户可以访问所有内容”。