<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前、后端分離權(quán)限控制設(shè)計(jì)和實(shí)現(xiàn)思路

          共 3173字,需瀏覽 7分鐘

           ·

          2021-12-18 18:41

          來(lái)自:薛?定?諤?的?貓

          鏈接:https://www.yuque.com/zhanghaofei/blog/xrpz9p

          簡(jiǎn)述


          近幾年隨著react、angular、vue等前端框架興起,前后端分離的架構(gòu)迅速流行。但同時(shí)權(quán)限控制也帶來(lái)了問(wèn)題。


          網(wǎng)上很多前、后端分離權(quán)限僅僅都僅僅在描述前端權(quán)限控制、且是較簡(jiǎn)單、固定的角色場(chǎng)景,滿足不了我們用戶、角色都是動(dòng)態(tài)的場(chǎng)景。且僅僅前端進(jìn)行權(quán)限控制并不是真正意義的權(quán)限控制,它只是減少頁(yè)面結(jié)構(gòu)暴露、增強(qiáng)用戶體驗(yàn)的功效。


          場(chǎng)景

          系統(tǒng)為后臺(tái)管理系統(tǒng),包含了用戶創(chuàng)建、用戶登錄、用戶管理自己的資源。用戶經(jīng)常會(huì)新增、刪除,也可以根據(jù)工作情況隨時(shí)調(diào)整頁(yè)面、功能權(quán)限,所以采用用戶-角色-頁(yè)面權(quán)限方案實(shí)現(xiàn)。


          為什么不行:

          • 根據(jù)前端路由表顯示左側(cè)菜單,但vue-router的路由表主要為了組織代碼,經(jīng)常我們所需要的菜單并非一致。比如某個(gè)前端路由a子路由有b、c,但菜單中我們想要直接一級(jí)菜單就顯示b、c或者將b、c各放到其他菜單下。所以這種非常不靈活。

          • 一個(gè)路由是菜單還是頁(yè)面?是否需要顯示到菜單中?是否驗(yàn)證權(quán)限?哪個(gè)角色或者用戶擁有權(quán)限?這些都需要寫(xiě)到前端路由里面,一旦有任何權(quán)限變動(dòng)就要大量調(diào)整代碼。

          • 如果權(quán)限寫(xiě)死在前端,那么角色或者用戶必須已知且固定不變。比如頁(yè)面1的meta增加屬性標(biāo)識(shí)可訪問(wèn)的角色為a和b


          頁(yè)面


          一個(gè)頁(yè)面即一個(gè)前端頁(yè)面,比如首頁(yè)、用戶管理頁(yè)、資源管理頁(yè)等。


          基本思路為:前端路由保持不變,數(shù)據(jù)庫(kù)存儲(chǔ)菜單結(jié)構(gòu)、頁(yè)面權(quán)限控制(可以直接做成一個(gè)頁(yè)面來(lái)方便管理)等,前端根據(jù)數(shù)據(jù)庫(kù)中的菜單結(jié)構(gòu)和權(quán)限信息來(lái)渲染一個(gè)菜單出來(lái)并只顯示其有權(quán)限的菜單,并在路由守衛(wèi)中進(jìn)行權(quán)限控制防止手動(dòng)輸入path越權(quán)打開(kāi)頁(yè)面

          1、前端路由(vue-router)中需要正常創(chuàng)建頁(yè)面及路由。

          2、數(shù)據(jù)庫(kù)存儲(chǔ)菜單結(jié)構(gòu)和頁(yè)面權(quán)限信息,

          • 菜單(目錄、非內(nèi)容頁(yè))可以自己創(chuàng)建,不必要求前端路由中有,因?yàn)檫@是指菜單的可視化的組織結(jié)構(gòu)

          • 頁(yè)面(內(nèi)容頁(yè))必須是前端路由中已有頁(yè)面,因?yàn)檫@是用戶需要訪問(wèn)的內(nèi)容。

          • 菜單和頁(yè)面組成上下級(jí)關(guān)系,一級(jí)可以是菜單也可以是內(nèi)容頁(yè),內(nèi)容頁(yè)也可以放在菜單下,不可見(jiàn)的內(nèi)容頁(yè)也可以放在一個(gè)普通內(nèi)容頁(yè)下,這樣理論(需要頁(yè)面菜單樣式支持)可以組成無(wú)限級(jí)菜單。面包屑導(dǎo)航也根據(jù)此層級(jí)遞歸查詢得到。

          • 菜單和頁(yè)面的基本屬性包括title(對(duì)應(yīng)路由title)、name(對(duì)應(yīng)路由name)、path(對(duì)應(yīng)路由path)、父級(jí)、類型(菜單/頁(yè)面)、是否可見(jiàn)(左側(cè)菜單欄是否顯示:部分頁(yè)面可能是頁(yè)面內(nèi)的鏈接進(jìn)去)、是否需要驗(yàn)證權(quán)限(部分頁(yè)面比如首頁(yè)無(wú)需驗(yàn)證權(quán)限大家都可以進(jìn)入)

          • 不需要控制權(quán)限且不需要顯示到左側(cè)菜單的路由這里可以不進(jìn)行管理,比如404頁(yè)面等

          3、前臺(tái)打開(kāi)后獲取獲取數(shù)據(jù)庫(kù)的所有菜單、頁(yè)面及結(jié)構(gòu),根據(jù)是否登錄、是否需要驗(yàn)證權(quán)限等進(jìn)行控制,或無(wú)權(quán)限跳轉(zhuǎn)至登錄頁(yè)

          4、用戶登錄成功后,再獲取用戶對(duì)應(yīng)的的頁(yè)面權(quán)限列表,使用上一步獲得的所有頁(yè)面、結(jié)構(gòu)和用戶擁有權(quán)限的列表渲染出一個(gè)菜單,只包含此用戶擁有權(quán)限的,提升用戶體檢,避免顯示大量用戶不能訪問(wèn)的菜單影響使用和不必要的功能暴露。

          5、路由守衛(wèi)中根據(jù)上一步獲得的權(quán)限列表判斷每個(gè)跳轉(zhuǎn),無(wú)權(quán)限可返回404或無(wú)權(quán)限頁(yè)面,防止用戶手動(dòng)輸入path越權(quán)訪問(wèn)


          頁(yè)面管理:

          頁(yè)面編輯:

          功能


          部分功能有事需要單獨(dú)控制權(quán)限,比如用戶管理頁(yè)面可能允許多個(gè)角色查看,但是其中的"創(chuàng)建用戶"功能只允許某一個(gè)角色使用,那么僅僅使用頁(yè)面權(quán)限是不夠。所以需要細(xì)粒度的功能權(quán)限控制。


          網(wǎng)上的方案都是說(shuō):根據(jù)資源控制增、刪、改、查等等,比如針對(duì)用戶就是用戶的創(chuàng)建、修改、刪除、查詢等。但是在我的實(shí)際使用中發(fā)現(xiàn)并不切合實(shí)際,最起碼對(duì)像我這種管理后臺(tái),資源并不單純的增刪改查,可能有其他地方的其他操作中也會(huì)對(duì)此用戶資源造成影響,比如禁用、刪除角色也要禁用、刪除用戶,那么這個(gè)權(quán)限到底屬于角色的權(quán)限還是屬于用戶的權(quán)限,或者后臺(tái)又改了,角色又影響了其他資源或者不再對(duì)用戶進(jìn)行操作,都會(huì)影響權(quán)限控制。


          所以更合理的方法應(yīng)該為將每個(gè)功能單獨(dú)進(jìn)行控制并和頁(yè)面進(jìn)行關(guān)聯(lián),且不限定必須是增、刪、改、查四種,可以任意定制,只需要與前后端開(kāi)發(fā)約定一個(gè)唯一的標(biāo)識(shí)即可。


          如上的例子中,用戶管理頁(yè)面下有用戶各種功能,角色管理頁(yè)面中也有個(gè)角色禁用、刪除功能,可以分別定義標(biāo)識(shí)為roledisable、roledelete,如果擁有roledelete權(quán)限即可,即使沒(méi)有userdelete權(quán)限,也可以直接刪除用戶,否則就不要給其role_delete權(quán)限。


          用戶登錄后,從數(shù)據(jù)庫(kù)獲取其所擁有的的權(quán)限列表并存入vuex,包含頁(yè)面和功能對(duì)應(yīng)關(guān)系,例如頁(yè)面name為user:{user: ['userdelete', 'userquery']},頁(yè)面中根據(jù)刪除按鈕可以v-if="hasPermission('user_delete')"判斷即可


          頁(yè)面功能管理:

          獲取用戶擁有的權(quán)限:

          角色


          一個(gè)角色類似于一個(gè)身份或崗位,每個(gè)角色有自己的權(quán)限范圍。

          一個(gè)角色可以擁有多個(gè)頁(yè)面權(quán)限。

          一個(gè)角色可以擁有多個(gè)功能權(quán)限。

          角色管理:

          角色分配權(quán)限:

          用戶


          用戶可以創(chuàng)建、刪除,一個(gè)用戶隨時(shí)可能變更工作內(nèi)容,或者身兼數(shù)職,所以可以為其分配一個(gè)或者多個(gè)角色,他擁有的角色的權(quán)限就是他的權(quán)限。此時(shí)已經(jīng)可以打通權(quán)限前端的權(quán)限分配,用戶-角色-頁(yè)面權(quán)限、功能權(quán)限。

          用戶管理:

          用戶分配角色:

          后端權(quán)限


          傳統(tǒng)前后端不分離的情況下,路由都在后端統(tǒng)一管理,簡(jiǎn)單的方法比如用戶管理頁(yè)面/user/那么他里面使用的接口都使用/user/add、/user/delete等相同前綴,那么只要判斷用戶擁有/user/權(quán)限就可以訪問(wèn)/user/*所有接口。


          前后端分離后面臨的問(wèn)題:

          • 前、后端分別有自己的路由,且一個(gè)頁(yè)面會(huì)同時(shí)調(diào)后端多個(gè)不同模塊下的接口,這樣一來(lái)就無(wú)法通過(guò)以上傳統(tǒng)方式判斷權(quán)限。


          如此一來(lái)嗎,就需要有前端頁(yè)面到后端接口的管理,明確一個(gè)頁(yè)面會(huì)調(diào)用哪幾個(gè)接口。這樣當(dāng)授權(quán)用戶頁(yè)面時(shí),系統(tǒng)就可以根據(jù)此關(guān)系推斷哪些接口具有權(quán)限。


          接口


          方案:

          • 需要控制權(quán)限的接口進(jìn)行上傳管理(可以做成管理頁(yè)面)

          • 每個(gè)頁(yè)面和功能可以關(guān)聯(lián)多個(gè)接口,比如用戶頁(yè)面關(guān)聯(lián)了用戶查詢接口和用戶編輯接口,用戶刪除功能關(guān)聯(lián)用戶刪除接口

          • 后端對(duì)請(qǐng)求的路徑進(jìn)行判斷,用戶->角色->頁(yè)面/功能->接口,擁有接口權(quán)限即允許訪問(wèn)

          • 前后端分團(tuán)隊(duì)開(kāi)發(fā),不容易一一對(duì)照,且前端有自己的路由(此路由受限于代碼組織結(jié)構(gòu))等等,無(wú)法使用傳統(tǒng)方式簡(jiǎn)單處理

          • 相同的接口可能會(huì)被前端多個(gè)頁(yè)面多次利用

          接口管理:

          頁(yè)面關(guān)聯(lián)接口、功能關(guān)聯(lián)接口:

          請(qǐng)求的接口無(wú)權(quán)限時(shí):

          接口后端權(quán)限控制


          后端控制其實(shí)很簡(jiǎn)單,只要前面管理功能做好即可,基本邏輯為:

          • 用戶訪問(wèn)接口

          • 判斷用戶和當(dāng)前path,根據(jù)用戶->角色->頁(yè)面/功能->接口 得到當(dāng)前用戶有權(quán)限的接口列表與當(dāng)前path相比

          • 若無(wú)權(quán)限(某些接口只需要登錄就能訪問(wèn)的,比如獲取用戶姓名信息的需要排除在外)則直接返回失敗,前端全局捕獲后給出無(wú)權(quán)限提示


          數(shù)據(jù)庫(kù)表示例


          紅色表為實(shí)體表,藍(lán)色表為關(guān)聯(lián)關(guān)系表?;緸橛脩?>角色->頁(yè)面/功能->后端接口

          往期推薦

          @Transactional 注解失效的 8 大場(chǎng)景,看看你都遇到過(guò)幾個(gè)?

          字節(jié)一面:說(shuō)說(shuō)本機(jī)號(hào)碼一鍵登錄如何實(shí)現(xiàn)?

          一個(gè)員工的離職成本有多恐怖!

          從零開(kāi)始用SpringBoot 搭了一套萬(wàn)能文件在線預(yù)覽系統(tǒng),我覺(jué)的挺好用!

          這 9 個(gè) Java 開(kāi)源項(xiàng)目 yyds

          12 個(gè)非常適合做外包項(xiàng)目的開(kāi)源后臺(tái)管理系統(tǒng)

          瀏覽 78
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产第一页精品先锋影音视频 | 欧美日韩性爱视频 | 国产精品久久丫 | www.AV网站 | 麻豆精品三级无码 |