我正在尝试在反应应用程序中实现 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;