基於導航守衛實現頁面的權限控制

前言前端

做爲一個前端開發,咱們有時候會遇到一些沒有權限訪問的頁面,或者經過點擊某個按鈕但卻沒有權限。鑑於本身遇到了這樣的問題,因此在這裏作一個總結後端

需求分析api

系統管理員可以進入角色頁面,而且經過功能權限或者頁面權限給用戶分配權限,包括用戶是否有權限訪問某個頁面,或者是經過編輯以及添加這種操做進入某個頁面,以下圖所示。 promise

能夠看到第二張圖,咱們給這個角色爲測試的用戶,對某個頁面的功能進行了權限設置,點擊肯定後,角色爲測試的用戶將沒法使用該頁面的編輯以及新增功能。 bash

到這裏還不算真正的達到了權限控制,這裏咱們只是經過對編輯以及新增這兩個功能進行了權限控制,從而阻止用戶進入編輯或者新增頁面。數據結構

實際上, 既然咱們不能經過點擊的方式進入頁面,那咱們能不能直接經過路由的方式直接訪問呢?答案是若是咱們沒有作路由權限的控制,那就是能夠的。異步

也就是說,就算我不能經過點擊編輯或者新增進入頁面,但只要我知道編輯或者新增的頁面對應的url, 我就可以訪問到這個頁面。函數

所以咱們必須從兩個方面對頁面進行權限控制。 由於經過點擊進入頁面的方式已經作了權限控制了,那麼剩下的就是限制經過url來訪問頁面了。學習

第一步, 點擊操做(編輯或者新增)的權限是如何控制的測試

這個應該根據後端接口返回的數據結構來決定, 比方說後端如今返回給我一個這樣的數據結構

{
  code: 0,
  data: [{
    comment: '編輯',            // 功能名稱
    checkStatus: false          // 功能權限
  }, {
    comment: '新增',
    checkStatus: true
  }]
}
複製代碼

對應的編輯頁面的route

routes: [{
  name: 'article-edit',
  path: '/article/edit',
  beforeEnter: (to, from, next) {
    http.get(apis.getButtonsPowerList, {
      params: {
        pageId: xxxx
      }
    }).then(res => {
      if(res.code === 0) {                                 // code爲0說明請求成功
        let btnsPowerList = res.data                       // 獲取按鈕權限列表
        for(let i = 0; i < btnsPowerList.length; i++) {
          if(btnsPowerList[i].comment === '編輯') {        // 找到comment爲編輯的按鈕
            if(btnsPowerList[i].checkStatus) {             // 判斷編輯按鈕的checkStatus是否爲true
              next()                                       // 若是爲true,表示有權限,則進入相應頁面
            } else {                                       // 不然提示用戶沒有訪問權限,而且退回上一頁面
              setTimeout(() => {
                window.history.go(-1)
              })
              alert('您沒有訪問該頁面的權限')
            }
          }
        }
      }
    })
  }
}]
複製代碼

從上述代碼來講,功能是實現了,可是像這樣的控制頁面權限的功能,咱們須要將其封裝起來,不然會形成大量的代碼冗餘。因此下面是封裝以後的代碼。

export function isAuthRoute(comment, pageId, next) {
  new Promise(resolve => {
    _isAuth(comment, pageId, resolve)
  }).then(res => {
    if(!res) {
      setTimeout(() => {
        window.history.go(-1)
      }, 1500)
      alert('您沒有訪問該頁面的權限')
    } else {
      next()
    }
  })
}
 
function _isAuth(comment, pageId, callback) {
  http.get(apis.getButtonsPowerList, {
    params: {
      pageId
    }
  }).then(res => {
    if(res.code === 0) {
      let btnsPowerList = res.data                      
      for(let i = 0; i < btnsPowerList.length; i++) {
        if(btnsPowerList[i].comment === comment) {       
          callback(btnsPowerList[i].checkStatus)
        }
      }
    }
  })
}
複製代碼

調用的方式也很簡單

routes: [{
  name: 'article-edit',
  path: '/article/edit',
  beforeEnter: (to, from, next) {
    isAuthRoute('編輯', pageId, next)
  }
}]
複製代碼

注意,以上的調用接口的方式以及傳參的內容,須要根據自身的需求來決定

總結

其實這部分的代碼,最多隻是提供了一個思路,由於不一樣的場景確定寫出來的代碼也是不同的。在這個需求當中,我學習到的東西更多的是一個執行順序的問題,咱們知道文中使用的 beforeEnter 會在進入頁面以前調用,可是請求數據的接口是異步的, 而咱們須要經過異步接口返回的數據來判斷是否有權限進入頁面,這意味着咱們必須先拿到數據再去作判斷,因此這個時候咱們更但願保持一個同步的順序,因此這裏才使用了promise因爲promise中的then中的回調函數必須等到resolve後纔會被執行, 所以咱們將resolve做爲參數傳遞給真正調用了接口的函數直到接口返回數據以後,再在接口請求完畢的回調裏面調用resolve,經過這樣的方式,就可以確保在作權限判斷的時候,必定可以拿到數據。

最後,若是可以幫到各位,請不要吝惜點贊哦,謝謝。

以上的內容來自於個人csdn博客,由於沒啥人看,就搬過來掘金了。 個人csdn地址: blog.csdn.net/huangguangy…

相關文章
相關標籤/搜索