首頁  >  文章  >  web前端  >  在VueJS中如何設定使用者權限

在VueJS中如何設定使用者權限

亚连
亚连原創
2018-06-08 11:47:042966瀏覽

本篇文章主要為大家講述了VueJS應用程式中管理使用者權限的詳細流程和方法,以及相關的程式碼展示,需要的朋友參考下吧。

在需要身份驗證的前端應用程式裡,我們常常想透過使用者角色來決定哪些內容可見。例如,遊客身分可以閱讀文章,但註冊使用者或管理員才能看到編輯按鈕。

在前端中管理權限可能會有點麻煩。你之前可能寫過這樣的程式碼:

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

作為代替方案,一個簡潔輕量的函式庫-CASL-可以讓管理使用者權限變得非常簡單。只要你用CASL定義了權限,並設定了當前用戶,就可以把上面的程式碼改為這樣:

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

在這篇文章裡,我會展示如何在前端應用裡使用Vue.js和CASL來管理權限。

CASL 速成課程

CASL可以讓你定義一系列規則來限制哪些資源對使用者可見。

例如,CASL規則能夠標明使用者可以對給定的資源和實例(貼文、文章、評論等)進行哪些CRUD(Create, Read, Update和Delete)操作。

假設我們有分類廣告網站。最顯而易見的規則是:

遊客可以瀏覽所有帖子

管理員可以瀏覽所有帖子,並且可以更新或刪除

使用CASL,我們用AbilityBuilder來定義規則。呼叫can來定義一條新規則。例如:

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

現在,就可以用定義的規則來檢查應用程式權限了。

import defineAbilitiesFor from './abilities';

let currentUser = {
 id: 999,
 name: "Julie"
 type: "registered",
};

let abilities = defineAbilitiesFor(currentUser.type);

Vue.component({
 template: `<p><p>
       <p>Please log in</p>
      `,
 props: [ &#39;post&#39; ],
 computed: {
  showPost() {
   return abilities.can(&#39;read&#39;, &#39;Post&#39;);
  }
 }
});

Demo 課程

作為演示,我做了一個用來展示分類廣告貼文的伺服器/客戶端應用程式。這個應用程式的規則是:使用者能夠閱讀帖子或發帖,但只能更新或刪除自己的帖子。

我用Vue.js和CASL來方便地運行和擴展這些規則,即使以後添加新的操作或實例也將很方便。

現在我就帶你一步一步來搭建這個應用程式。如果你想一睹為快,請戳這個Github repo。

定義使用者權限

我們在 resources/ability.js中定義使用者權限。 CASL的一個優點是與環境無關,也就是說它既能在Node中運行,也能在瀏覽器中運行。

我們會把權限定義寫到一個CommonJS模組裡來確保Node的兼容性(Webpack能讓這個模組用在客戶端)。

resources/ability.js

const casl = require(&#39;casl&#39;);

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

下面我們來剖析這段程式碼。

define方法的第二個參數,我們透過呼叫can來定義了權限規則。這個方法的第一個參數是你要允許的CRUD操作,第二個是資源或實例,在這個範例中是Post。

注意第二個can的調用,我們傳了一個物件作為第三個參數。這個物件是用來測試user屬性是否符合我們提供的user物件。如果我們不這麼做,那麼不光創建者可以刪帖,誰都可以隨便刪了。

resources/ability.js

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

CASL檢查實例來指派權限時,需要知道實例的type。一種解決方式是把具有subjectName方法的對象,作為define方法的第一個參數,subjectName方法會傳回實例的類型。

我們透過在實例中傳回type來達成目的。我們需要保證,在定義Post物件時,這個屬性是存在的。

resources/ability.js

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

最後,我們把我們的權限定義封裝到一個函數裡,這樣我們就可以在需要測試權限的時候直接傳進一個user物件。在下面的函數中會更容易理解。

resources/ability.js

const casl = require(&#39;casl&#39;);

module.exports = function defineAbilitiesFor(user) {
 ...
};

Vue 中的存取權規則

現在我們想要在前端應用程式中檢查一個物件中,使用者俱有哪些CRUD權限。我們需要在Vue組件中存取CASL規則。這是方法:

引入Vue和 abilities plugin。這個插件會把CASL加到Vue的原型上,這樣我們就能在元件內呼叫了。

在Vue 應用程式內引入我們的規則(例: resources/abilities.js)。

定義目前使用者。實戰中,我們是透過伺服器來取得使用者資料的,在這個例子中,我們簡單地硬編碼到到專案裡。

牢記,abilities模組export一個函數,我們稱它為defineAbilitiesFor。我們會向這個函數傳入使用者物件。現在,無論何時,我們可以透過偵測一個物件來得出目前使用者擁有何種權限。

新增abilities插件,這樣我們就可以在元件中像這樣來進行測試了:this.$can(...)。

src/main.js

import Vue from &#39;vue&#39;;
import abilitiesPlugin from &#39;./ability-plugin&#39;;

const defineAbilitiesFor = require(&#39;../resources/ability&#39;);
let user = { id: 1, name: &#39;George&#39; };
let ability = defineAbilitiesFor(user.id);
Vue.use(abilitiesPlugin, ability);

Post 實例

我們的應用程式會使用分類廣告的貼文。這些表述貼文的物件會從資料庫檢索,然後再被伺服器傳給前端。例如:

我們的Post實例中有兩個屬性是必須的:

type屬性。 CASL會使用 abilities.js中的subjectName回呼來檢查正在測試的是哪一個實例。

user属性。这是发帖者。记住,用户只能更新和删除他们发布的帖子。在 main.js中我们通过defineAbilitiesFor(user.id)已经告诉了CASL当前用户是谁。CASL要做的就是检查用户的ID和user属性是否匹配。

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

这两个post对象中,ID为1的George,拥有第一个帖子的更新删除权限,但没有第二个的。

在对象中测试用户权限

帖子通过Post组件在应用中展示。先看一下代码,下面我会讲解:

src/components/Post.vue

<template>
 <p>
  <p>

   <br /><small>posted by </small>
  </p>
  <button @click="del">Delete</button>
 </p>
</template>
<script> import axios from &#39;axios&#39;;

 export default {
  props: [&#39;post&#39;, &#39;username&#39;],
  methods: {
   del() {
    if (this.$can(&#39;delete&#39;, this.post)) {
     ...
    } else {
     this.$emit(&#39;err&#39;, &#39;Only the owner of a post can delete it!&#39;);
    }
   }
  }
 } </script>
<style lang="scss">...</style>

点击Delete按钮,捕获到点击事件,会调用del处理函数。

我们通过this.$can('delete', post)来使用CASL检查当前用户是否具有操作权限。如果有权限,就进一步操作,如果没有,就给出错误提示“只有发布者可以删除!”

服务器端测试

在真实项目里,用户在前端删除后,我们会通过 Ajax发送删除指令到接口,比如:

src/components/Post.vue

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

服务器不应信任客户端的CRUD操作,那我们把CASL测试逻辑放到服务器:

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(&#39;delete&#39;, post)) {
  posts = posts.filter(cur => cur !== post);
  res.json({ success: true });
 } else {
  res.json({ success: false });
 }
});

CASL是同构(isomorphic)的,服务器上的ability对象就可以从abilities.js中引入,这样我们就不必复制任何代码了!

封装

此时,在简单的Vue应用里,我们就有非常好的方式管理用户权限了。

我认为this.$can('delete', post) 比下面这样优雅得多:

if (user.id === post.user && post.type === &#39;Post&#39;) {
 ...
}

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

JS中的单例模式实现对数据增删改查

使用Vue仿制今日头条(详细教程)

React开发如何配置eslint

以上是在VueJS中如何設定使用者權限的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn