成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何從零設計結(jié)構清晰、操作友好的權限管理模塊

開發(fā) 開發(fā)工具
當我們談及權限的時候,很容易想到在用戶發(fā)起請求時,對接口做一層權限驗證,或者是對數(shù)據(jù)庫讀寫限制權限,簡單粗暴。因為是以用戶操作為出發(fā)點進行限制。

前言

在開講之前,先列舉幾個場景:

  • 場景一:Hi,今天那個銷售總監(jiān)說要設立幾個銷售經(jīng)理的職位,然后每個經(jīng)理管理自己小組的銷售員,我們把用戶的銷售數(shù)據(jù)按組分開來吧。
  • 場景二:Mario,今天那個市場部的說要分立幾個板塊,公眾號的管理所有文章投稿評論,推廣管各平臺宣傳策略方案與實施,對,競品的相關資料數(shù)據(jù)也要分立出來,我們要把這些分開來。之前討論的銷售部的事情和這個沒關系哦。
  • 場景三:那個,xx店的店主說,他管理的兩家門店,想同時處理兩家店的事情,需要兼顧兩家的銷售、采購的數(shù)據(jù)。人家提的需求場景有道理,你給他做一下吧,對了,不要影響其他店的管理哦!
  • 場景四:今天總部的運營小x說,他們需要以門店、部門、單個用戶的角度看所有的運營數(shù)據(jù),給他們做一下吧,每天導 excel 要瘋了。

開始

當我們談及權限的時候,很容易想到在用戶發(fā)起請求時,對接口做一層權限驗證,或者是對數(shù)據(jù)庫讀寫限制權限,簡單粗暴。因為是以用戶操作為出發(fā)點進行限制,所以我們在一個接口的 handler 中定義:

  1. if not user in [‘xxx’, ‘yyy’, ‘zzz’]: 
  2.           return ‘has no permission!’ 

或者在處理數(shù)據(jù)模型的 model 層定義:

  1. access_users  = [‘xxx’, ‘yyy’, ‘zzz’] 

這樣限制住了用戶的操作行為。不過這個硬編碼的形式簡直慘不忍睹,今天加一個接口,我們在 handler 代碼中來一段這個權限定義,明天另一個 handler 的權限變動了,我們再去改一下那個代碼。你說寫在一個裝飾器中統(tǒng)一管理,ok,那么在添加、修改 handler 的同時,還要去找到對應的具有該權限的用戶,在裝飾器中進行相關定義。在一個產(chǎn)品不斷迭代的情景下,這樣是不能被接受的。所以我們有必要引入一個模型來規(guī)范化權限控制。

結(jié)構化管理

通過以上情景,我們很容易得到一種權限結(jié)構模型(參考 django)以 user(單一用戶)、group(用戶組)、permissions(單一權限)三層兩兩之間多對多的關系,實現(xiàn)了當用戶請求接口 APIa,此時進行獲取用戶,獲取用戶所屬組,獲取所屬組所具備的權限,若獲取不到記錄,則限制掉此次請求。運用這個模型,我們每次將 permissions 定義成:module、function 的形式,同時定義 request method 。這樣將具有權限的 group 關聯(lián)到一個 permission(即一個 handler)上。同時將用戶關聯(lián)到用戶組,從而可以在不斷變動權限的情況下,配置一次對應關系,將用戶權限限制到單個 handler 上。

結(jié)構化管理

用 python 的同學知道,由于 python decorator @的語法糖,我們很喜歡用這種形式來處理這些與業(yè)務邏輯無關的代碼,例如:日志記錄、檢查緩存、檢查 user session等。有時候在一個方法裝飾器寫的像蓋樓一樣,稍不留神就忘記了。有時候開發(fā)者對項目不熟悉,在寫一個新的接口之后,配置了權限,卻忘記加裝飾器,導致這部分一直沒有被限制。

  1. @route() 
  2. @login_required 
  3. @check_cache 
  4. @add_log 
  5. @permission_verify 
  6. @transaction.atomic 
  7. def interface_a(): 

所以在這里引入一個中間件,專門處理這個事情,不必每次增加額外代碼。

中間件運行發(fā)生在后端 route dispatching 的時候,每次的請求我們根據(jù)請求的 session 找到 user、找到對應的 user group, 再找到 permissions,通過定義的具有權限 module function 與請求的 handler 比對,若不同則限制掉。

  1. def permission_middleware(): 
  2.     permissions =  request.get.user_permissions() 
  3.     if ‘{}_{}’.format(handler.__class__, handler.func_name) not in permissions: 
  4.         return permission_denied 

這樣后端限制邏輯比較結(jié)構化,節(jié)省了很多麻煩,方便修改和管理。同時具有較好的擴展性,我們將 user 定義為單一用戶對象,將 permissions 看作單一 handler 對象,可以把所有門店、部門、小組、小群體等均劃分到 group 一層 。幾乎大部分的業(yè)務需求均可以對應實現(xiàn)。邏輯準確,嗯,很***。

限制閉環(huán),對象細化

第二天 PM 來了,說 xx 部門的小 x 講他們部門里面的工作內(nèi)容需要分類,(我在點頭,心里想:嗯嗯,我給你們每一個分類加一個 group 配置 user 權限)一個工作分類有許多工作者,有一個管理者,管理者需要看所有工作者的工作進度,工作內(nèi)容管理者也同樣可以進行(心里想:嗯嗯,我再加一個管理者的 group 所有權限一樣,單獨加一個工作進度查看的權限)同時!1分類下的管理者,還可以看2、3工作分類下的小 y 小 z 的工作進度!(我心里想:what?這不科學吧)PM 繼續(xù)說,因為他們工作要對接,是需要查看的功能(我想:那管理者不作分類不就好了,所有的內(nèi)容都可以看)并不能全部看到!PM 接著說,他的主要工作還是本分類下的工作內(nèi)容,只是查看一下其他分類下的幾個人的進度,你不能給他把所有人的內(nèi)容都展示出來吧,況且有些還是保密的。

這確實是一個問題,不僅僅是在這種特殊的情況,只要涉及到針對某一個用戶,或者某一個具體內(nèi)容做操作限制,就是實現(xiàn)不了的。經(jīng)過輾轉(zhuǎn)反側(cè),發(fā)現(xiàn)我們之前做的只是將權限限制在操作行為上,沒有形成閉環(huán),操作哪些對象沒有定義。每一次限制默認是所有對象。這樣雖然方便管理,但是有些場景不能滿足需求。于是引入權限操作對象范圍的概念:

在之前的 permissions 一層上加入:

  1. 是否有對象粒度限制
  2. 限制的哪個 model 的 object
  3. 可操作的object id list。

由于這部分是對于數(shù)據(jù)過濾的處理,所以我們無法在中間件完成這個操作。將這部分放入數(shù)據(jù)處理層(DAO 層)進行過濾是個不錯的主意。首先我們在數(shù)據(jù)處理方法中,在上下文獲取本次請求的 user 對象,按老辦法將他的 permissions 統(tǒng)統(tǒng)獲取到,這時,按照我們預先定義的:是否有對象粒度限制進行判斷,需要限制則根據(jù)當前處理的 model 過濾出操作的 object id list。這樣在返回數(shù)據(jù)的時候,所有記錄均為對其具有操作權限的對象。

  1. object_id_list = request.user.permissions.get_object_id_list() 
  2. if need_limit_object and model == request.user.permissions.get_model: 
  3.         sql = ‘select * from model where id in {}’.format(tuple(object_id_list)) 
  4.         return fetch_data(sql) 

現(xiàn)在我們滿足了所有(至少是目前為止所遇到的)業(yè)務需求,后續(xù)權限的所有需求也可以按照這個思路進行相關配置處理,并得以解決(美好的愿望^_^)。

前端限制提高體驗

至此,我們開發(fā)工作會變得很愉快,邏輯清晰且結(jié)構嚴謹。與此同時,給 c 端用戶的體驗就是,哪里不會點哪里,點完哪里不給你。給一個美如畫的頁面或者是彈窗還算好的,跳個403、404或是500想必也見過。此時用戶只有一句 mmp,什么破玩意不玩了。

前端限制提高體驗

所以,權限在前端預先限制勢在必行,好在我們多數(shù)情況下用到了模版引擎,很方便的在頁面上進行權限判斷。在服務器端渲染頁面的時候,根據(jù)當前請求的用戶,獲取到所有權限,在某一個 DOM 上簡單隨意的寫上一句判斷代碼,將我們在中間件中匹配 handler 的過程放到模版渲染的過程,這樣將沒有權限的條目過濾掉,還用戶一個清靜的世界,同樣可以避免點到不該點的東西。

  1. {% if user.permissions.can_modify_xxx %} 
  2. <a href=”/modify_xxx/”>修改xxx</a> 
  3. {% endif %} 

如果是在不用模版引擎的情況下,我們就需要在頁面在瀏覽器渲染的時候,加一個 ajax 請求加載到用戶的權限列表,用js后期去掩蓋掉不該看到的東西。

前端組件化整理

這樣極大程度的提高了用戶體驗,但是回顧一下我們的做法,編寫一個新的功能,處理掉權限所有關系配置之后,需要根據(jù)這個 module function 字符串在頁面上所有用到的地方寫一句判斷語句,這樣非常麻煩。而且如果想要修改一個權限的定義,簡直是災難。為了解決這個問題,我們不得不借鑒一下組件化的設計模式,即模版復用。用模版引擎的繼承、導入可以實現(xiàn)這個目的。當然 react 是天生的組件化設計理念。我們在一個最上級組件初始化的時候?qū)⒃撚脩艟哂械臋嘞蘖斜韽姆掌鞫死。鎯Ρ镜兀缓笠来蜗蛳铝魅氲礁骷壸咏M件中,每個組件配置一個 id(可以與 module function 字符串一致,也可以做一次映射)當組件在權限列表中找到自己的對應的 id 則進行渲染。最終整個頁面根據(jù)權限列表將所有可以顯示的部分全部渲染出來。

前端組件化整理

剛才提到的組件id這是前后端限制的關鍵,后端根據(jù) module function 判斷 handler 處理,前端根據(jù) id 判斷渲染與否,那么這個配置應該是前端寫好組件由后端配置,還是后端提供配置權限入口,由前端自行配置呢?

前后端分工配合

當我們討論開發(fā)模式的時候,總會遇到這樣一個問題:

1. 前后端分離還是不分離

  • 分離時前端工作量加重,路由、組件加載、部署等都要處理,有時候項目不是很大,這種分離得不償失,但是好處是前后端各司其職,處理自己的部分,不會產(chǎn)生不必要的工作量。
  • 不分離的情況就是運用模版引擎,前端提供靜態(tài)頁面,服務器端渲染,這樣有的時候在后端處理數(shù)據(jù)的同時可能將頁面樣式或者動畫效果破壞掉,然后又要兩端反復修改,好處是開發(fā)簡單,一些功能簡單且比較單一,可以直接一并處理。

無論分離還是不分離,提供一個配置服務這個中間產(chǎn)物是有必要的,分離時我們可以讓前端在寫好組件后,將自己的組件id配置在系統(tǒng)中,后端按照正常的限制邏輯進行。不分離時,直接根據(jù)前端頁面的編寫的 id 進行配置,這部分可以由后端完成。有了這個公共區(qū)的系統(tǒng),想必大家都是很開心的,又能一起愉快的玩耍(coding)了。現(xiàn)在處理這個問題的開源項目有很多,比如基于 django admin、flask admin 等流行的后臺管理項目,就可以很好的搭建這種定制化的公共配置部分。

當然,具體的設計結(jié)構需要根據(jù)系統(tǒng)需求作相應的變通,可能有些場景限制粒度無要求,我們可以不作操作對象的閉環(huán),如果是權限嚴格要求的場景(Mario 遇到的場景)就顯得有必要了。前端限制在追求用戶體驗的情況是有必要的,組件化會將結(jié)構理得非常清晰,同時工作量也有所增加。公共區(qū)的配置模塊就像一個前后端的樞紐,或者說是一個契約,不僅是在權限限制上,在所有配合開發(fā)的場景都是有所幫助的。

【本文是51CTO專欄機構“豈安科技”的原創(chuàng)文章,轉(zhuǎn)載請通過微信公眾號(bigsec)聯(lián)系原作者】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2022-02-10 10:10:03

數(shù)據(jù)庫表權限表數(shù)據(jù)庫操作

2011-05-11 14:50:54

URL

2011-05-19 15:25:20

數(shù)據(jù)庫結(jié)構

2023-11-21 15:17:37

人工智能數(shù)據(jù)管理

2024-11-11 08:31:32

2020-10-20 10:46:10

DevOps運維體系

2017-11-15 09:49:03

運維服務器端系統(tǒng)

2021-10-27 11:40:18

風險管理/零信任

2022-05-31 08:04:30

前端設計模式

2025-05-15 01:00:00

2024-11-25 09:10:03

2015-10-13 09:15:18

App登錄模塊設計

2010-05-20 13:56:17

Fedora 13

2023-06-29 06:13:52

2022-07-05 09:38:47

模型RBACABAC

2021-12-31 09:04:39

軟件設計開發(fā)函數(shù)

2010-04-09 17:35:22

2023-04-11 11:19:45

2021-03-02 07:31:26

WebApiweb

2021-07-12 17:23:47

零設計可視化引擎
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产午夜精品久久久 | 黄色操视频| 国产一区二区黑人欧美xxxx | 自拍偷拍亚洲一区 | 国家一级黄色片 | 天天综合91 | 亚洲精品一区二区网址 | 91久久精品一区二区三区 | 国产精品18久久久久久白浆动漫 | 日韩一区二区福利 | 999热精品 | 午夜精品一区二区三区在线视 | 国外成人在线视频网站 | 国产91色在线 | 亚洲 | 久久久久久久久91 | 国产免费看 | 日韩综合在线播放 | 国产一区二区毛片 | 蜜桃日韩 | 欧美在线一区二区三区 | 国产精品成人一区二区 | 伊人二区 | 日日天天 | 福利国产| 成人国产精品色哟哟 | 激情欧美一区二区三区中文字幕 | 99九九久久 | 国产精品久久久久久吹潮日韩动画 | 成人在线视频免费观看 | 久久久久久久久久久久91 | 亚洲91精品 | 亚洲 欧美 日韩在线 | 欧美日韩成人一区二区 | 国产人成精品一区二区三 | 久久精品亚洲精品国产欧美 | 成年人在线播放 | 黄色在线免费观看 | 中文字幕亚洲国产 | 蜜臀av日日欢夜夜爽一区 | 精品久久久久久一区二区 | 久久久久久久久久久一区二区 |