Details about managing user permissions in VueJS applications and vuejs User Permissions

Source: Internet
Author: User

Details about managing user permissions in VueJS applications and vuejs User Permissions

In front-end applications that require authentication, we often want to use user roles to determine what content is visible. For example, visitors can read articles, but only registered users or administrators can see the edit button.

It may be a bit difficult to manage permissions on the front end. You may have written such code before:

if (user.type === ADMIN || user.auth && post.owner === user.id ) { ...}

As an alternative solution, a simple and lightweight database, CASL, can simplify the management of user permissions. As long as you define permissions with CASL and set the current user, you can change the above Code to the following:

if (abilities.can('update', 'Post')) { ...}

In this article, I will show you how to use Vue. js and CASL to manage permissions in front-end applications.

CASL quick course

CASL allows you to define a series of rules to limit which resources are visible to users.

For example, the CASL rule can indicate which CRUD (Create, Read, Update, and Delete) operations can be performed on the given resources and instances (posts, articles, comments, etc.

Suppose we have a classified advertising website. The most obvious rule is:

Visitors can browse all posts

The administrator can browse all posts and update or delete them.

With CASL, we use AbilityBuilder to define rules. Call can to define a new rule. For example:

onst { AbilityBuilder } = require('casl');export function(type) { AbilityBuilder.define(can => {  switch(type) {   case 'guest':    can('read', 'Post');    break;   case 'admin':    can('read', 'Post');    can(['update', 'delete'], 'Post');    break;   // Add more roles here  } }};

Now, you can use the defined rules to check application permissions.

import defineAbilitiesFor from './abilities';let currentUser = { id: 999, name: "Julie" type: "registered",};let abilities = defineAbilitiesFor(currentUser.type);Vue.component({ template: `<div><div>       <div>Please log in</div>      `, props: [ 'post' ], computed: {  showPost() {   return abilities.can('read', 'Post');  } }});
Demo Course

As a demonstration, I made a server/client application to display classified ad posts. The rule for this application is: users can read or post, but can only update or delete their own posts.

I use Vue. js and CASL to conveniently run and extend these rules, even if new operations or instances are added in the future.

Now I will show you how to build this application step by step. If you want to speed up, please stamp this Github repo.

Define User Permissions

We define user permissions in resources/ability. js. One advantage of CASL is that it has nothing to do with the environment, that is, it can run both in Node and in the browser.

We will write the permission definition to a CommonJS module to ensure Node compatibility (Webpack allows this module to be used on the client ).

Resources/ability. js

const casl = require('casl');module.exports = function defineAbilitiesFor(user) { return casl.AbilityBuilder.define(  { subjectName: item => item.type },  can => {   can(['read', 'create'], 'Post');   can(['update', 'delete'], 'Post', { user: user });  } );};

Next we will analyze this code.

The second parameter of the define method, which is defined by calling can. The first parameter of this method is the CRUD operation you want to allow, and the second parameter is the resource or instance. In this example, It is Post.

Note that for the second can call, an object is passed as the third parameter. This object is used to test whether the user attribute matches the user object we provide. If we do not do this, not only can the Creator Delete the post, but anyone else can delete it.

Resources/ability. js

...casl.AbilityBuilder.define( ... can => {  can(['read', 'create'], 'Post');  can(['update', 'delete'], 'Post', { user: user }); });

When CASL checks instances to assign permissions, you need to know the instance type. One solution is to use an object with the subjectName method as the first parameter of the define method. The subjectName method returns the instance type.

We can achieve our goal by returning type in the instance. We need to ensure that this attribute exists when defining the Post object.

Resources/ability. js

...casl.AbilityBuilder.define( { subjectName: item => item.type }, ...);

Finally, we encapsulate our permission definition into a function so that we can directly upload the permission to a user object when we need to test the permission. The following functions are easier to understand.

Resources/ability. js

const casl = require('casl');module.exports = function defineAbilitiesFor(user) { ...};
Access permission rules in Vue

Now we want to check the CRUD permissions of an object in the front-end application. We need to access the CASL rules in the Vue component. This is the method:

Introduce Vue and abilities plugin. This plug-in will add CASL to the Vue prototype so that we can call it in the component.

Introduce our rules (for example, resources/abilities. js) in the Vue application ).

Define the current user. In practice, we obtain user data through the server. In this example, we simply hardcode the data to the project.

Keep in mind that the abilities module export is a function called defineAbilitiesFor. We will input user objects to this function. Now, at any time, we can detect an object to determine the permissions of the current user.

Add the abilities plug-in so that we can test the components like this: this. $ can (...).

Src/main. js

import Vue from 'vue';import abilitiesPlugin from './ability-plugin';const defineAbilitiesFor = require('../resources/ability');let user = { id: 1, name: 'George' };let ability = defineAbilitiesFor(user.id);Vue.use(abilitiesPlugin, ability);
Post instance

Our applications use classified ad posts. The post objects are retrieved from the database and then transmitted to the front-end by the server. For example:

Two attributes in our Post instance are required:

Type attribute. CASL uses the subjectName callback in abilities. js to check which instance is being tested.

User attribute. This is the poster. Remember, users can only update and delete posts they post. In main. js, we have told CASL who the current user is by defineAbilitiesFor (user. id. CASL is to check whether the user ID and user attributes match.

let posts = [ {  type: 'Post',  user: 1,  content: '1 used cat, good condition' }, {  type: 'Post',  user: 2,  content: 'Second-hand bathroom wallpaper' }];

In the two post objects, George with ID 1 has the permission to update and delete the first post, but does not have the permission to delete the second post.

Test user permissions in objects

Post is displayed in the application through the Post component. Let's take a look at the code. I will explain it below:

Src/components/Post. vue

<template> <div>  <div>   <br /><small>posted by </small>  </div>  <button @click="del">Delete</button> </div></template><script> import axios from 'axios'; export default {  props: ['post', 'username'],  methods: {   del() {    if (this.$can('delete', this.post)) {     ...    } else {     this.$emit('err', 'Only the owner of a post can delete it!');    }   }  } } </script><style lang="scss">...</style>

Click the Delete button to capture the Click Event and call the del processing function.

We use this. $ can ('delete', post) to use CASL to check whether the current user has operation permissions. If you have the permission, perform further operations. If you do not have the permission, an error is returned, indicating that "only the publisher can delete the permission !"

Server Test

In a real project, after the user deletes the front-end, we will send the deletion command to the interface through Ajax, for example:

Src/components/Post. vue

if (this.$can('delete', post)) { axios.get(`/delete/${post.id}`, ).then(res => {  ... });}

The server should not trust the client's CRUD operations, so we should put the CASL test logic on the server:

Server. js

app.get("/delete/:id", (req, res) => { let postId = parseInt(req.params.id); let post = posts.find(post => post.id === postId); if (ability.can('delete', post)) {  posts = posts.filter(cur => cur !== post);  res.json({ success: true }); } else {  res.json({ success: false }); }});

CASL is homogeneous (isomorphic). The ability object on the server can be introduced from abilities. js, so that we don't have to copy any code!

Encapsulation

In this case, in a simple Vue application, we have a very good way to manage user permissions.

I think this. $ can ('delete', post) is much more elegant than the following:

if (user.id === post.user && post.type === 'Post') { ...}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.