跳转至主要内容

Frontend Integration

Casbin.js 把 Casbin 风格的访问控制带到前端:定义权限(例如来自后端),并用它们显示 / 隐藏界面元素或控制路由。它可以在 manual 模式(在代码中设置权限)或 auto 模式(从 API 获取)下工作。

安装​

npm install casbin.js
npm install casbin

或

yarn add casbin.js

前端框架​

框架类型作者描述
react-authzReactCasbinCasbin.js的React封装
rbac-reactReact@daobeng在 React 中用高阶组件、CASL 和 Casbin.js 实现基于角色的访问控制
vue-authzVueCasbinCasbin.js的Vue封装
angular-authzAngularCasbinCasbin.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 服务会有几个问题:

  1. 客户端连接时,enforcer 会初始化并从后端存储拉取全部策略。高并发时会给数据库带来压力,并消耗大量网络带宽。
  2. 把全部策略暴露给客户端会带来安全隐患。
  3. 客户端和服务器紧密耦合,开发和维护都更复杂。

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.