Vue 前端應用進行身份認證許可權控制的一種方法

趙津發表於2018-11-03

如果大家覺得有用,更多的模組請點選檢視

點選訪問demo

Vue 前端應用進行身份認證許可權控制的一種方法

掃碼訪問

許可權控制可以分為:

  • 身份認證許可權控制
  • RBAC許可權控制

下面介紹一下vue-viewplus 一個簡化Vue應用開發的工具庫中的login-state-check.js 身份認證許可權控制模組。

使用該模組可以讓應用使用一個包含正規表示式的陣列LoginStateCheck#checkPaths,來定義需要進行身份認證(登入)才能訪問的頁面資源(路由的path),這樣做的好處就在於,我們不用向很多應用那些去修改路由元件中的mate欄位來確認哪一個路由元件需要進行身份認證許可權控制。

一般的應用在許可權控制這一塊,一般有兩種需求,一種是基於RBAC許可權模型的管理端應用,而大多數應用只需要控制那些頁面需要使用者登入才能訪問;當前模組預設認為所有頁面都是公共資源,如果要進行身份認證許可權控制,可以這樣定義:

loginStateCheck: {
    checkPaths: [
      /User\/Manage/
    ],
    ...
複製程式碼

這樣所有使用者管理資源就都需要登入才能進行訪問了。

匹配規則:如果在LoginStateCheck#checkPaths需要身份認證規則集中,那麼就需要檢視使用者是否登入,如果沒有登入就拒絕訪問; 當然外掛內部還是依賴router的導航守衛來進行攔截控制;

注:

  • 該模組維護了一個vuex state vplus#loginState,來持有使用者登入狀態,在頁面重新整理的時候也通過快取資料來對其進行恢復;
  • 這個狀態建議配合UtilHttp#accessRules.sessionTimeOut和UtilHttp#accessRules.onSessionTimeOut,來使用,也就是一般應用都是後臺來控制登入狀態或者說會話的時長,你需要在sessionTimeOut中配置後臺會話超時返回的錯誤碼,這樣外掛就會自動將當期模組的vplus#loginState設定為false,這樣就幫我們管理了這個不可控狀態;
  • 如果沒有配置在改列表裡面的都被視為公共交易,即不需要身份認證就可以訪問;

示例

模擬一個身份認證訪問控制例子

個人管理頁面/Demo/Manage/User是一個需要進行身份認證才能訪問的router頁面,需要首先登陸才能進行訪問,如果後臺返回強制簽退的結果,那麼登陸狀態將會被設定為false,接著要訪問之前可以進入的個人管理頁面也會被自動攔截;

瀏覽線上示例

示例程式碼:

<template>
  <div id="LoginStateCheck">
    <group title="模擬一個簡單的身份認證許可權控制流程" label-width="15em" class="bottom-group">
      <box gap="10px 10px">
        <cell title="點選測試訪問一個需要登入之後才能訪問的頁面" link="/Demo/Manage/User"></cell>
      </box>
      <box gap="10px 10px">
        <x-button @click.native="doLogin">登入</x-button>
      </box>
      <box gap="10px 10px">
        <x-button @click.native="doLogout">退出登入</x-button>
      </box>
      <box gap="10px 10px">
        <x-button @click.native="doForcedWithdrawal">模擬強制簽退</x-button>
      </box>
    </group>
  </div>
</template>


<script type="text/ecmascript-6">
  import demoMixin from './demo-mixin'
  import { Cell } from 'vux'

  export default {
    mixins: [demoMixin],
    components: {
      Cell
    },
    methods: {
      doLogin() {
        this.$vp.ajaxMixin('LOGIN').then(data => {
          this.doLoginBtnState = false
          this.$vp.modifyLoginState(true)
          console.log(`登入後狀態為: ${this.$vp.isLogin()}`)
          this.$vp.uiToast('模擬登入成功')
        })
      },
      doLogout() {
        console.log(`登出前狀態為: ${this.$vp.isLogin()}`)
        this.$vp.modifyLoginState(false)
        console.log(`登入後狀態為: ${this.$vp.isLogin()}`)
        this.$vp.uiToast('退出登入完成')
      },
      doForcedWithdrawal() {
        this.$vp
          .ajaxMixin('FORCEDWITHDRAWAL', {
            mode: 'GET'
          })
          .catch(resp => {
            console.error(`模擬強制簽退完成:${resp}`)
            this.$vp.uiToast('模擬強制簽退完成')
          })
      }
    },
    created() {
      console.log(
        `登入前狀態為: ${this.$vp.isLogin()}`
      )
    }
  }
</script>
複製程式碼

示例所需配置:

Vue.use(ViewPlus, {
  // ...
  loginStateCheck: {
    checkPaths: [
      /Manage/
    ],
    onLoginStateCheckFail(to, from, next) {
      this.dialog(`onLoginStateCheckFail被回撥:待訪問資源【${to.path}】是需要登入才能訪問,請先登入`, {
        action() {
          next(false)
        }
      })
      // 更新狀態進度條
      store.commit('updateLoadingStatus', false)
    }
  }
})
複製程式碼

配置

checkPaths

  /**
     * 需要進行身份認證檢查的路由path路徑集合
     * {Array<Object>}
     * <p>
     * 陣列中的item,必須要是一個**正規表示式字面量**,如`[/^((\/Interbus)(?!\/SubMenu)\/.+)$/]`
     * <p>
     * 匹配規則:如果在`LoginStateCheck#checkPaths`**需要身份認證規則集**中,那麼就需要檢視使用者是否登入,如果沒有登入就拒絕訪問
     */
    checkPaths = []
複製程式碼

onLoginStateCheckFail

  /**
     * [*] `$vp#onLoginStateCheckFail(to, from, next)`
     * <p>
	 * 身份認證檢查失敗時被回撥
     */
    onLoginStateCheckFail = null
複製程式碼

一般你可以需要這樣實現該函式:

onLoginStateCheckFail(to, from, next) {
  this.uiToast('您尚未登入,請先登入')
  next('/User/Login')
}
複製程式碼

isLogin

  /**
     * 【可選】在初始化外掛的時候,預製登入狀態,如使用者可能已經在原生客戶端登入完畢,故可以通過此配置來初始化使用者狀態相關資訊;
     */
    isLogin = false
複製程式碼

API介面

isLogin

/**
   * $vp.isLogin()
   * 獲取使用者登入狀態
   * <p>
   * @return {boolean} 如果處於登入狀態返回true,否則返回false,直接通過獲取外掛vuex state中對應`loginState`的值
   */
  isLogin()
複製程式碼

modifyLoginState

/**
   * $vp.modifyLoginState(isLogin = false)
   * 修改登入狀態
   * <p>
   * 會修改外掛vuex state中對應`loginState`的值
   * <p>
   * 注意使用者的登入狀態前端只是一個`臨時維護`,即在服務端設定的session或者token有效期到了之後,服務端一般會返回**會話超時**這樣的錯誤,故我們在`util-http`模組還對此作了預留處理,詳見`utilHttp#accessRules.onSessionTimeOut`配置
   * 所以在這裡我們只用操作vuex中的狀態即可
   * @param {Boolean} [isLogin=false]       外掛使用vuex時候維護的登入狀態
   */
  modifyLoginState(isLogin = false)
複製程式碼

restoreLoginState

/**
   * $vp.restoreLoginState()
   * 恢復外掛中對應`store#loginState`的登入相關狀態,在當前模組重新安裝的時候,一般對應就是頁面重新整理的時候
   */
  restoreLoginState()
複製程式碼

相關文章