最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端權限控制和管理實現(xiàn)步驟詳解

 更新時間:2025年03月15日 09:34:26   作者:太陽與星辰  
這篇文章主要介紹了前端權限控制的相關概念和實現(xiàn)思路,前端權限控制不僅可以提高安全性,還可以提升用戶體驗,文中將實現(xiàn)的步驟介紹的非常詳細,需要的朋友可以參考下

1.前言

在Web系統(tǒng)中,一直以來權限都只是后端程序所控制的。因為Web 系統(tǒng)圍繞的是數(shù)據(jù),而和數(shù)據(jù)庫最緊密接觸的是后端程序。所以在很長的一段時間內,權限一直都只是后端程序要考慮的話題。 但是隨著前后端分離架構的流行,越來越多的項目也在前端進行權限控制。

2.權限相關概念

2.1權限的分類

(1)后端權限

從根本上講前端僅僅只是視圖層的展示,權限的核心是在于服務器中的數(shù)據(jù),所以后端才是權限的關鍵,后端權限可以控制某個用戶是否能夠查詢數(shù)據(jù),是否能夠修改數(shù)據(jù)等操作。

ps:后端如何知道該請求是哪個用戶發(fā)過來的

  • cookie
  • session
  • token

ps:后端的權限設計RBAC(一般五張表)

  • 用戶
  • 角色
  • 權限
  • 還有兩張關系表

(2)前端權限

本質上來說,前端權限的控制就是控制前端的視圖層的展示和前端所發(fā)送的請求。但是只有前端權限控制沒有后端權限控制是萬萬不可的。 前端權限控制只是達到錦上添花的效果。

2.2前端權限的意義

如果僅從能夠修改服務器中數(shù)據(jù)庫中的數(shù)據(jù)層面上講,確實只在后端做控制就足夠了,那為什么越來越多的項目也進行了前端權限的控制,主要有這幾方面的好處。

  • 降低非法操作的可能性;
  • 不怕贓偷就怕賊惦記,在頁面中展示出一個就算點擊了也最終會失敗的按鈕,勢必會增加有心者非法操作的可能性;
  • 盡可能排除不必要清求,減輕服務器壓力,沒必要的請求,操作失敗的清求,不具備權限的清求,這些應該壓根就不需要發(fā)送,請求少了,自然也會減輕服務器的壓力;
  • 提高用戶體驗;
  • 根據(jù)用戶具備的權限為該用戶展現(xiàn)自己權限范圍內的內容,避免在界面上給用戶帶來困擾,讓用戶專注于分內之事;

3.前端權限控制思路

3.1菜單的權限控制

在登錄請求中,會得到用戶的權限數(shù)據(jù),當然,這個需要后端返回數(shù)據(jù)的支持。前端根據(jù)權限數(shù)據(jù),展示對應的菜單。點擊菜單,才能查看相關的界面。

3.2界面的權限控制

如果用戶沒有登錄,手動在地址欄敲入登錄后主界面的地址,則需要跳轉到登錄界面。
如果用戶已經登錄,如果手動敲入非權限內的地址,則需要跳轉404 界面。

3.3按鈕的權限控制

在某個菜單的界面中,還得根據(jù)權限數(shù)據(jù),展示出可進行操作的按鈕,比如刪除、修改、增加等按鈕。

3.4接口的權限控制

如果用戶通過非常規(guī)操作,比如通過瀏覽器調試工具將某些禁用的按鈕變成啟用狀態(tài),此時發(fā)的請求也應該被前端所攔截。

4.實現(xiàn)步驟

4.1菜單欄控制

用戶登錄之后,服務端返回一個數(shù)據(jù),這個數(shù)據(jù)有菜單列表和token,我們把這個數(shù)據(jù)放入到vuex中,然后主頁根據(jù)vuex中的數(shù)據(jù)進行菜單列表的渲染。

問題:刷新界面后vuex數(shù)據(jù)會消失,菜單欄會消失解決:將數(shù)據(jù)存儲在sessionStorage中,并讓其和vuex中的數(shù)據(jù)保持同步(用專門的持久化插件也可以)store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //每次點擊頁面中的刷新按鈕,state中的數(shù)據(jù)就會根據(jù)下面的數(shù)據(jù)重新初始化
    rightList: JSON.parse(sessionStorage.getItem('rightList') || '[]'),
    username: sessionStorage.getItem('username'),
  },
  mutations: {
    setRightList(state, newData) {
      state.rightList = newData
      sessionStorage.setItem('rightList', JSON.stringify(newData)) //sessionStorage只能存儲字符串
    },
    setUsername(state, newData) {
      state.username = newData
      sessionStorage.setItem('username', newData)
    },
  },
  actions: {},
  getters: {},
})

4.2界面的控制

登錄成功后,將token數(shù)據(jù)存儲在sessionStorage中,用來判斷是否登錄

(1)路由導航守衛(wèi)

router/index.js:

router.beforeEach((to, from, next) => {
      //頁面跳轉之前做攔截動作,判斷token是否存在
      if (to.path === '/login') next()
      else {
        const token = sessionStorage.getItem('token')
        if (!token) next('/login')
        else {
          next()
        }
      }
    })

問題:這樣用戶在登錄之后就可以訪問其他界面了,但如果用戶A登錄之后只能訪問a頁面不能訪問b頁面,但是這時候他還是可以通過地址欄輸入進入到b頁面。

解決:當然我們也可以設置路由導航守衛(wèi),但是如果有多個頁面,設置會非常不方便,并且對于用戶A來說,它是不用訪問b頁面的,這時候我們可以對A不顯示b頁面,這個時候我們就用到了動態(tài)路由。

(2)動態(tài)路由

根據(jù)當前用戶所擁有的的權限數(shù)據(jù)來動態(tài)添加所需要的路由。

先定義好所有的路由規(guī)則:router/routerMap.js:

import Users from '@/components/user/Users.vue'
import Roles from '@/components/role/Roles.vue'
import GoodsCate from '@/components/goods/GoodsCate.vue'
import GoodsList from '@/components/goods/GoodsList.vue'

const userRule = { path: '/users', component: Users }
const roleRule = { path: '/roles', component: Roles }
const goodRule = { path: '/goods', component: GoodsList }
const categoryRule = { path: '/categories', component: GoodsCate }

const routesMap = {
  users: userRule,
  roles: roleRule,
  goods: goodRule,
  categories: categoryRule,
}
export { routesMap }

登錄成功之后動態(tài)添加路由,注意這個initDynamicRoutes的方法需要暴露出去在登錄頁面調用

這樣當用戶A在地址欄輸入自己不能訪問的路由時,就不會跳轉到該頁面,而是跳轉到404頁面。

問題:如果我們重新刷新的話動態(tài)路由就會消失,動態(tài)路由是在登錄成功之后才會調用,刷新的時候并沒有調用,所以動態(tài)路由沒有添加上。

解決:可以在app.vue中的created中調用添加動態(tài)路由的方法

4.3按鈕的控制

雖然用戶可以看到某些界面了,但是對于這個界面的一些按鈕,該用戶可能是沒有權限的。 因此,我們需要對組件中的一些按鈕進行控制,用戶不具備權限的按鈕就隱藏或者禁用,而在這塊的實現(xiàn)中,可以把該邏輯放到自定義指令中

比如我們可以根據(jù)后端返回的數(shù)據(jù)right來判斷用戶有什么權限,如下圖。

添加自定義指令 控制按鈕

import Vue from 'vue'
import store from '../store';
import router from '../router';
const permission = {
  inserted(el, binding) {
    //傳過來的參數(shù)中,action表示被綁定的按鈕是什么操作;effect表示當用戶沒有這個操作權限的時候,
    //應該如何如理這個按鈕
    const action = binding.value.action
    const effect = binding.value.effect
    //獲取用戶在當前路由中所具有的權限列表
    let currentPathPermissions = router.currentRoute.meta   
    if(currentPathPermissions.indexOf(action) == -1){
      if(effect === 'disabled'){
        el.disabled = true
        el.classList.add('is-disabled') //element-ui需要的處理
      }
      else
        el.parentNode.removeChild(el)
        //el.style.display = 'none'
    }
  }
}
Vue.directive('permission', permission)

4.4接口的控制

(1)請求控制

除了登錄請求都得要帶上token,這樣服務器才可以鑒別你的身份。這塊需要配置axios的請求攔截器。

如果發(fā)出了非權限內的請求,應該直接在前端范圍內阻止,雖然這個請求發(fā)到服務器也會被拒絕。

非權限內的請求:比如a用戶是不能夠操作該頁面的按鈕的,但是他通過f12調試把按鈕改為可點擊,如果我們不對這個請求進行處理,那么這個請求就會發(fā)送出去。

//當前模塊中具備的權限關系映射
const actionMapping = {
  get: 'view', //查看-->get請求
  post: 'add', //添加-->post請求
  put: 'edit', //編輯-->put請求
  delete: 'delete', //刪除-->delete請求
}
//請求攔截控制
axios.interceptors.request.use((request) => {
  // console.log(request.url);
  // console.log(request.method);
  if (request.url !== 'login') {
    //除了登錄請求以外,在請求頭中全部添加上token
    request.headers.Authorization = sessionStorage.getItem('token')
    //將請求方式映射成為操作類型的權限
    const action = actionMapping[request.method]
    //獲取用戶在當前路由下所具有的權限
    const currentRight = router.currentRoute.meta
    if (currentRight && currentRight.indexOf(action) === -1) {
      //沒有權限發(fā)送請求,通過報錯攔截
      alert('沒有權限!')
      return Promise.reject(new Error('沒有權限'))
    }
  }
  return request
})

(2)響應控制

得到了服務器返回的狀態(tài)碼401,代表token 超時或者被篡改了,此時應該強制跳轉到登錄界面。

axios.interceptors.response.use((response) => {
  if (response.data.meta.status === 401) {
    //返回401表示token失效,返回登陸界面
    router.push('/login')
    sessionStorage.clear()
    window.location.reload()
  }
  return response
})

5.小結

  • 前端權限的實現(xiàn)必須要后端提供數(shù)據(jù)支持,否則無法實現(xiàn)。
  • 返回的權限數(shù)據(jù)的結構,前后端需要溝通協(xié)商怎樣的數(shù)據(jù)用起來才最方便。

5.1菜單控制

  • 權限的數(shù)據(jù)需要在多組件之間共享,因此采用vuex
  • 防止刷新界面權限數(shù)據(jù)丟失,所以需要使用sessionStorage進行持久化,并目要保證兩者的同步。

5.2界面控制

  • 路由的導航守衛(wèi)可以防止跳過登錄界面。
  • 動態(tài)路由可以讓不具備權限的界面的路由規(guī)則壓根就不存在。

5.3按鈕控制

  • 路由規(guī)則中可以增加路由元數(shù)據(jù)meta。
  • 通過路由對象可以得到當前的路由規(guī)則以及存在此規(guī)則中的meta數(shù)據(jù)。
  • 自定義指令可以很方便的實現(xiàn)按鈕控制。

5.4請求和響應控制

  • 請求攔截器和響應攔截器的使用。
  • 請求方式的約定restful。

總結 

到此這篇關于前端權限控制和管理實現(xiàn)的文章就介紹到這了,更多相關前端權限控制和管理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 實例講解JS中pop使用方法

    實例講解JS中pop使用方法

    在本篇文章里我們給大家分享了關于JS中pop使用方法的實例內容,有興趣的朋友們學習下。
    2019-01-01
  • JS清除選擇內容的方法

    JS清除選擇內容的方法

    這篇文章主要介紹了JS清除選擇內容的方法,較為詳細的分析了js操作文本的技巧,需要的朋友可以參考下
    2015-01-01
  • ES6入門教程之Array.from()方法

    ES6入門教程之Array.from()方法

    這篇文章主要給大家介紹了關于ES6入門教程之Array.from()方法的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用ES6具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-03-03
  • javascript中內置對象Math的介紹及用法案例

    javascript中內置對象Math的介紹及用法案例

    Math對象是一個內置對象,具有數(shù)學常數(shù)和函數(shù)的屬性和方法,不是一個函數(shù)對象,下面這篇文章主要給大家介紹了關于javascript中內置對象Math的介紹及用法案例的相關資料,需要的朋友可以參考下
    2022-03-03
  • 使用javascript做時間倒數(shù)讀秒功能的實例

    使用javascript做時間倒數(shù)讀秒功能的實例

    今天小編就為大家分享一篇關于使用javascript做時間倒數(shù)讀秒功能的實例,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • uni-app小程序分享功能實現(xiàn)方法舉例

    uni-app小程序分享功能實現(xiàn)方法舉例

    這篇文章主要給大家介紹了關于uni-app小程序分享功能實現(xiàn)方法的相關資料,uni-app中有分享的API接口,但是需要現(xiàn)在QQ或者微信等開發(fā)者平臺上注冊賬號,驗證公司信息,而且只能分享圖片或者文本等內容,需要的朋友可以參考下
    2023-07-07
  • 判斷文件是否正在被使用的JS代碼

    判斷文件是否正在被使用的JS代碼

    這篇文章主要介紹了判斷文件是否正在被使用的JS代碼,有需要的朋友可以參考一下
    2013-12-12
  • js只執(zhí)行1次的函數(shù)示例

    js只執(zhí)行1次的函數(shù)示例

    本文通過代碼示例給大家展示了如何讓javascript只執(zhí)行一次,如何實現(xiàn)這種功能呢?通過下面這段就可以輕松搞定了。
    2016-07-07
  • 使用JavaScript實現(xiàn)一個靜態(tài)鏈表

    使用JavaScript實現(xiàn)一個靜態(tài)鏈表

    這篇文章主要為大家詳細介紹了如何使用JavaScript實現(xiàn)一個靜態(tài)鏈表,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-06-06
  • javascript九宮格圖片隨機打亂位置的實現(xiàn)方法

    javascript九宮格圖片隨機打亂位置的實現(xiàn)方法

    這篇文章主要為大家詳細介紹了javascript九宮格圖片隨機打亂位置的實現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03

最新評論

华坪县| 洪洞县| 莱阳市| 库尔勒市| 胶州市| 龙岩市| 涞水县| 如皋市| 张家界市| 毕节市| 五指山市| 兰考县| 闵行区| 昔阳县| 黄骅市| 太原市| 嘉义县| 和静县| 合山市| 泸州市| 宜黄县| 安平县| 岫岩| 蒲城县| 盐津县| 石城县| 葫芦岛市| 元氏县| 岑溪市| 河津市| 南乐县| 沽源县| 海南省| 伊通| 颍上县| 叶城县| 治县。| 黑山县| 南江县| 灌云县| 东平县|