前端集成
Casbin.js 将 Casbin 风格的访问控制引入前端:定义权限(例如从后端获取),并使用它们来显示/隐藏 UI 或路由用户。它支持 manual 模式(您在代码中设置权限)或 auto 模式(从 API 获 取)。
安装
npm install casbin.js
npm install casbin
或
yarn add casbin.js
前端框架
| Framework | Type | Author | Description |
|---|---|---|---|
| react-authz | React | Casbin | Casbin.js 的 React 包装器 |
| rbac-react | React | @daobeng | 在 React 中使用高阶组件、CASL 和 Casbin.js 实现基于角色的访问控制 |
| vue-authz | Vue | Casbin | Casbin.js 的 Vue 包装器 |
| angular-authz | Angular | Casbin | Casbin.js 的 Angular 包装器 |
快速开始
在 manual 模式下配置 Casbin.js,以便在前端应用中显式设置权限:
const casbinjs = require("casbin.js");
// Set the user's permission:
// He/She can read `data1` and `data2` objects and can write `data1` object
const permission = {
"read": ["data1", "data2"],
"write": ["data1"]
}
// Run casbin.js in manual mode, which requires you to set the permission manually.
const authorizer = new casbinjs.Authorizer("manual");
使用授权器实例,你可以通过 authorizer.can() 和 authorizer.cannot() 来检查权限。这两个方法都返回 JavaScript Promise(参见 MDN 文档),因此请使用 then() 方法来处理结果:
result = authorizer.can("write", "data1");
result.then((success, failed) => {
if (success) {
console.log("you can write data1");
} else {
console.log("you cannot write data1");
}
});
// output: you can write data1
cannot() 方法的工作方式完全相同:
result = authorizer.cannot("read", "data2");
result.then((success, failed) => {
if (success) {
console.log("you cannot read data2");
} else {
console.log("you can read data2");
}
});
// output: you can read data2
success 参数表示查询已无错误地完成——而不是指权限被授予。同样,failed 与查询错误相关,而非权限被拒绝。
请参阅我们的 React 示例以了解 Casbin.js 的实际用法。
权限对象
Casbin.js 使用 JSON 对象来表示访问者的权限。例如:
{
"read": ["data1", "data2"],
"write": ["data1"]
}
该对象表明访问者可以读取 data1 和 data2 两个对象,但只能写入 data1。
高级用法
Casbin.js 提供了前端访问控制与后端 Casbin 服务之间的无 缝集成。
使用 auto 模式并在初始化 Casbin.js Authorizer 时指定你的后端端点。它将自动同步权限并管理前端授权状态:
const casbinjs = require('casbin.js');
// Set your backend Casbin service URL
const authorizer = new casbinjs.Authorizer(
'auto', // mode
{endpoint: 'http://your_endpoint/api/casbin'}
);
// Set your visitor.
// Casbin.js will automatically sync the permission with your backend Casbin service.
authorizer.setUser("Tom");
// Evaluate the permission
result = authorizer.can("read", "data1");
result.then((success, failed) => {
if (success) {
// Some frontend procedure ...
}
});
在后端,暴露一个端点(如 REST API)来生成供前端使用的权限对象。在你的 API 控制器中,调用 CasbinJsGetUserPermission 来构建权限对象。以下 Beego 示例演示了这种模式:
你的端点应返回类似以下的响应:
{
"other":"other",
"data": "What you get from `CasbinJsGetPermissionForUser`"
}
// Router
beego.Router("api/casbin", &controllers.APIController{}, "GET:GetFrontendPermission")
// Controller
func (c *APIController) GetFrontendPermission() {
// Get the visitor from the GET parameters. (The key is "casbin_subject")
visitor := c.Input().Get("casbin_subject")
// `e` is an initialized instance of Casbin Enforcer
c.Data["perm"] = casbin.CasbinJsGetPermissionForUser(e, visitor)
// Pass the data to the frontend.
c.ServeJSON()
}
目前,CasbinJsGetPermissionForUser 仅在 Go Casbin 和 Node-Casbin 中可用。如需在其他语言中获得支持,请 提交 issue 或在下方留言。
API 参考
setPermission(permission: string)
设置权限对象。主要用于 manual 模式。
setUser(user: string)
设置访问者身份并刷新权限。主要用于 auto 模式。
can(action: string, object: string)
检查用户是否可以对 object 执行 action。
cannot(action: string, object: string)
检查用户是否 不能 对 object 执行 action。
canAll(action: string, objects: Array<object>)
检查用户是否可以对 objects 中的 所有 对象执行 action。
canAny(action: string, objects: Array<object>)
检查用户是否可以对 objects 中的 任意 对象执行 action。
为什么选择 Casbin.js
人们常常疑惑 Node-Casbin 和 Casbin.js 之间的区别。Node-Casbin 是 Casbin 针对 Node.js 环境的核心实现,通常部署在服 务端用于访问控制管理。Casbin.js 是一个前端库,帮助你在客户端为网页用户应用 Casbin 授权逻辑。
直接为前端授权构建 Casbin 服务存在几个问题:
- 当客户端连接时,enforcer 会初始化并从后端存储拉取所有策略。高并发会给数据库带来压力并消耗大量网络带宽。
- 将所有策略暴露给客户端会产生安全漏洞。
- 客户端与服务端的紧耦合增加了开发和维护的难度。
Casbin.js 通过在客户端级别管理用户权限来解决这些挑战。其核心功能是通过 fetch 操作将当前用户的权限与后端 Casbin 服务进行同步。一旦获取到权限数据,开发者就可以使用 Casbin.js 接口在前端控制用户行为。
这种方法消除了重复的 enforcer 初始化,减少了客户端与服务端之间的消息大小,并避免了在前端暴露所有策略。用户仅访问自己的权限,而无需了解访问控制模型或其他用户的权限。此外,Casbin.js 有效地解耦了客户端和服务端的授权逻辑。
Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.