Frontend Integration
Casbin.js 把 Casbin 风格的访问控制带到前端:定义权限(例如来自后端),并用它们显示 / 隐藏界面元素或控制路由。它可以在 manual 模式(在代码中设置权限)或 auto 模式(从 API 获取)下工作。
安装
npm install casbin.js
npm install casbin
或
yarn add casbin.js
前端框架
| 框架 | 类型 | 作者 | 描述 |
|---|---|---|---|
| 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 实例,就可以用 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 指的是查询出错,而不是权限被拒绝。
Casbin.js 的实际用法见我们的 React 示例。
权限对象
Casbin.js 用一个 JSON 对象表示访客的权限。例如:
{
"read": ["data1", "data2"],
"write": ["data1"]
}
这个对象表示访客可以读取 data1 和 data2,但只能写入 data1。
高级用法
Casbin.js 让前端访问控制与后端 Casbin 服务无缝衔接。
初始化 Casbin.js 的 Authorizer 时使用 auto 模式并指定后端接口。它会自动同步权限,并管理前端的授权状态:
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()
}
目前只有 Go Casbin 和 Node-Casbin 提供 CasbinJsGetPermissionForUser。如需其他语言的支持,请 提交 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 通过在客户端管理用户权限来解决这些问题。核心功能是通过一次请求,把当前用户的权限与后端 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.