Skip to main content

Frontend Usage

Casbin.js is a Casbin addon that facilitates your access-control management in the frontend application.

Installation

npm install casbin.js
npm install casbin

or

yarn add casbin.js

Frontend Middlewares

MiddlewareTypeAuthorDescription
react-authzReactCasbinReact wrapper for Casbin.js
rbac-reactReact@daobengRole Based Access Control in React using HOCs, CASL and Casbin.js
vue-authzVueCasbinVue wrapper for Casbin.js
angular-authzAngularCasbinAngular wrapper for Casbin.js

Quick Start

You can use the manual mode in your frontend application and set the permissions whenever you wish.

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");

Now we have an authorizer, authorizer. We can get permission rules from it by using the authorizer.can() and authorizer.cannot() APIs. The return values of these 2 APIs are JavaScript Promises (details here), so we should use the then() method of the return value like this:

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

The cannot() API is used in the same way:

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

In the code above, the success variable in the parameters means the request gets the result without throwing an error and doesn't mean that the permission rule is true. The failed variable is also unrelated to the permission rules. It only makes sense when something goes wrong in the process of the request.

You can refer to our React example to see a practical usage of Casbin.js.

Permission Object

Casbin.js will accept a JSON object to manipulate the corresponding permission of a visitor. For example:

{
"read": ["data1", "data2"],
"write": ["data1"]
}

The permission object above shows that the visitor can read the data1 and data2 objects, while they can only write the data1 objects.

Advanced Usage

Casbin.js provides a perfect solution for integrating your frontend access-control management with your backend Casbin service.

Use the auto mode and specify your endpoint when initializing the Casbin.js Authorizer, it will automatically sync the permission and manipulate the frontend status.

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 ...
}
});

Correspondingly, you need to expose an interface (e.g. a RestAPI) to generate the permission object and pass it to the frontend. In your API controller, call CasbinJsGetUserPermission to construct the permission object. Here is an example in Beego:

note

Your endpoint server should return something like

{
"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()
}
note

Currently, the CasbinJsGetPermissionForUser API is only supported in Go Casbin and Node-Casbin. If you want this API to be supported in other languages, please raise an issue or leave a comment below.

API List

setPermission(permission: string)

Set the permission object. Always used in manual mode.

setUser(user: string)

Set the visitor identity and update the permission. Always used in auto mode.

can(action: string, object: string)

Check if the user can perform action on object.

cannot(action: string, object: string)

Check if the user cannot perform action on object.

canAll(action: string, objects: Array<object>)

Check if the user can perform action on all objects in objects.

canAny(action: string, objects: Array<object>)

Check if the user can perform action on any one of the objects.

Why Casbin.js

People may wonder about the difference between Node-Casbin and Casbin.js. In a word, Node-Casbin is the core of Casbin implemented in the NodeJS environment, and it's normally used as an access-controlling management toolkit at the server ends. Casbin.js is a frontend library that helps you use Casbin to authorize your webpage users at the client side.

Normally, it is not proper to directly build up a Casbin service and do the authorization/enforcement tasks at a web frontend application due to the following problems:

  1. When someone turns on the client, the enforcer will be initialized, and it will pull all the policies from the backend persistent layers. A high concurrency could bring tough pressure on the databases and cost a lot of network throughput.
  2. Loading all policies to the client side could bring security risks.
  3. It is difficult to separate the client and server as well as facilitate agile development.

We need a tool that eases the process of using Casbin at the frontend. Actually, the core of Casbin.js is the manipulation of the current user's permission at the client side. As you mentioned, Casbin.js does a fetch from a specified endpoint. This procedure will sync the permission of the user with the backend Casbin service. After having the permission data, developers can use Casbin.js interfaces to manage the behavior of the user at the frontend side.

Casbin.js avoids the two problems mentioned above: Casbin service will no longer be pulled up repeatedly, and the size of passing messages between the client and the server is reduced. We also avoid storing all the policies at the frontend. The user can only access their own permission, but has no knowledge about the access-control model and other users' permissions. Besides, Casbin.js can also efficiently decouple the client and the server in authorization management.