摘要:文章通過節(jié)點(diǎn),角色,用戶和這三者之間兩兩關(guān)系的數(shù)據(jù)庫(kù)表設(shè)計(jì),實(shí)現(xiàn)了三個(gè)好處:系統(tǒng)的維護(hù)靈活度增加了,新增功能只需要簡(jiǎn)單幾步就可以加入菜單;用戶對(duì)應(yīng)多個(gè)角色可以減少了每個(gè)用戶設(shè)定權(quán)限的工作量;方便的生成每個(gè)用戶對(duì)應(yīng)的菜單。
關(guān)鍵詞:訪問控制;權(quán)限管理;RBAC
中圖分類號(hào):TP3092 文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1006-8937(2014)15-0074-01
1要求
①有三級(jí)菜單。②對(duì)不同的用戶顯示相應(yīng)的菜單,用戶有權(quán)限的菜單才顯示,沒有權(quán)限的不顯示。③系統(tǒng)能在使用的同時(shí)不斷的加功能,也就是菜單會(huì)動(dòng)態(tài)的增加。
2解決方法
①系統(tǒng)訪問URL形如:http://serverName/appName/mod-
ule/action/id/1/,這里的module是控制器,也是獨(dú)立的功能,action是方法,一個(gè)module對(duì)應(yīng)0~N個(gè)action。②使用在用戶和菜單之間,加入角色概念。比如“管理員”有查看日志的功能?!爱a(chǎn)品”一般就是編輯功能。那產(chǎn)品主管就可以選定管理員+產(chǎn)品就可以了。而不用再新建一個(gè)“產(chǎn)品主管”的用戶。
使用5個(gè)數(shù)據(jù)表來實(shí)現(xiàn)這個(gè)功能,分別是Node(節(jié)點(diǎn)表)見表1,Role(角色表)見表2,user(用戶表)見表3,Node_role(節(jié)點(diǎn)-角色對(duì)應(yīng)表)見表4,User_Role(用戶-角色對(duì)應(yīng)表)見表5,數(shù)據(jù)表部分字段設(shè)計(jì)如下。
3基礎(chǔ)菜單的添加
這是整個(gè)系統(tǒng)初始化的基礎(chǔ)步驟,假設(shè)添加一級(jí)菜單三個(gè)排序分別為:基本信息、訂單、用戶。基本信息下有兩個(gè)二級(jí)菜單:新聞、商品,應(yīng)該加入菜單表如:
①一級(jí)菜單的添加:INSERT INTO Node(name,level_1,level_2,level_3)VALUES(‘info’,1,0,0)。②二級(jí)菜單的添加:INSERT INTO Node(name,level_1,level_2,level_3)VALUES(‘news’,1,1,0)。
一,二級(jí)菜單的關(guān)聯(lián)完全是依據(jù)排序,和ID沒有關(guān)系,這樣的好處是:和界面設(shè)定的菜單直接對(duì)應(yīng)起來,后面要加功能(三級(jí)菜單)的時(shí)候想加入第幾個(gè)一級(jí)菜單和第幾個(gè)二級(jí)菜單就可以直接填寫,直觀方便。
4菜單增加
這是基礎(chǔ)步驟。每當(dāng)一個(gè)功能(控制器module)完成上線后,要把這個(gè)功能加入到系統(tǒng)的菜單。就是添加節(jié)點(diǎn)。一個(gè)控制器可以有N個(gè)節(jié)點(diǎn),至少有一個(gè)節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)是它本身。其他的節(jié)點(diǎn)表示方法(action),比如常見的添加add,修改edit,刪除edit。
那么,假設(shè)把一個(gè)有添加add,修改edit,刪除del三個(gè)方法的焦點(diǎn)新聞功能加到二級(jí)菜單新聞(這個(gè)二級(jí)菜單新聞是前面定義好的,一級(jí)菜單排序1,二級(jí)菜單排序1)下,那么SQL語(yǔ)句如:
INSERT INTO NodeVALUES(,0,2,‘jd-news’,’焦點(diǎn)新聞’,1,1,1);
得到ID假設(shè)為888,接著添加方法:
INSERT INTO Node VALUES(,888,‘a(chǎn)dd’,,3,0,0,0);
INSERT INTO Node VALUES(,888,‘edit’,,3,0,0,0);
INSERT INTO Node VALUES(,888,‘del’,,3,0,0,0);
這樣,根據(jù)level_1,level_2,level_3的值,就可以得出控制器節(jié)點(diǎn)的排序位置,如果level_2,level_3為0,表示這個(gè)是一個(gè)一級(jí)菜單,如果level_3為0,那么這就是一個(gè)二級(jí)菜單,如果全為0,則表示這是某個(gè)控制器的方法。
5權(quán)限設(shè)定
分兩步:①給角色分配權(quán)限,最好是角色間的權(quán)限不重復(fù)。加入node_role節(jié)點(diǎn)角色對(duì)應(yīng)表。②給用戶設(shè)定角色,一個(gè)用戶可以多個(gè)角色,加入user_role用戶角色對(duì)應(yīng)表。
6前端菜單生成
這是重要的步驟,用戶登錄進(jìn)入系統(tǒng)后,生成這個(gè)用戶對(duì)應(yīng)的菜單。方法如下:
①獲取用戶ID,假設(shè)為888,初始化一個(gè)菜單數(shù)組menu。②查詢Node(節(jié)點(diǎn)表)生成菜單,先按順序生成一級(jí)菜單列表,加入菜單數(shù)組menu,每個(gè)菜單標(biāo)志‘n’。③循環(huán)一級(jí)菜單,按順序生成每個(gè)二級(jí)菜單,加入菜單數(shù)組menu,每個(gè)菜單標(biāo)志一個(gè)‘n’。④循環(huán)二級(jí)級(jí)菜單,按順序,并關(guān)聯(lián)用戶-角色對(duì)應(yīng)表和節(jié)點(diǎn)-角色對(duì)應(yīng)表,檢索出這個(gè)用戶可以訪問的節(jié)點(diǎn)列表。一一加入菜單數(shù)組,加入菜單數(shù)組的每個(gè)節(jié)點(diǎn),都把它所對(duì)應(yīng)的二級(jí)菜單和一級(jí)菜單的‘n’標(biāo)志去掉,已經(jīng)去掉的就忽略。⑤再循環(huán)一次菜單數(shù)組menu,把所有標(biāo)志為‘no’的一級(jí)菜單和二級(jí)菜單去掉。
這就得到一個(gè)可用在前端顯示的菜單數(shù)組,形如:
$menu=array(\"基本信息\"=>array(\"新聞\"=>array(\"焦點(diǎn)新聞\"), \"商品\"),
\"用戶\"=>array(\"所有用戶\"=>array(\"用戶統(tǒng)計(jì)\"),);
‘no’標(biāo)志的作用在于,一開始設(shè)定這個(gè)菜單不顯示,那么如果有查詢到這個(gè)菜單下的一個(gè)控制器(三級(jí)菜單)有權(quán)限,那么這個(gè)三級(jí)菜單所屬的二級(jí)菜單和一級(jí)菜單,都會(huì)顯示。最后再把‘no’標(biāo)志的菜單都刪掉,這樣用戶就看不到自己沒有權(quán)限的其他菜單了。
7后端代碼驗(yàn)證
為了防止有些非法用戶試圖通過直接輸入U(xiǎn)RL來訪問,那么在后端應(yīng)該要做個(gè)檢測(cè)機(jī)制??梢栽诠差惱飳憘€(gè)檢測(cè)的方法。并且所有的控制器都繼承這個(gè)公共類。那么這個(gè)檢測(cè)的方法實(shí)現(xiàn)原理如下:
①獲取用戶的user_id,訪問的模型名module,訪問的方法名action。②查詢node表中這個(gè)節(jié)點(diǎn)的node_id,這里分兩小步:查詢node表中name=‘module’的ID假設(shè)為m_id;查詢node表中name=‘a(chǎn)ction’AND pid=m_id的ID為n_id。③依靠user_role.roleid=node_role.role_id這個(gè)條件,關(guān)聯(lián)用戶-角色對(duì)應(yīng)表和節(jié)點(diǎn)-角色對(duì)應(yīng)表這兩個(gè)表,查詢where node_
id=n_id的記錄。④如果有記錄,表示可以訪問;如果沒有記錄,拒絕訪問。
參考文獻(xiàn):
[1] 信科,楊峰,楊光旭,等.基于RBAC權(quán)限管理系統(tǒng)的優(yōu)化設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)技術(shù)與發(fā)展,2011,(7).
[2] 倪東英,張曉麗.基于RBAC的用戶權(quán)限管理的設(shè)計(jì)與實(shí)現(xiàn)[J] 濟(jì)南大學(xué)學(xué)報(bào)(自然科學(xué)版),2010,(2).
[3] 馬麗,馬世龍,眭躍飛,等.一種RBAC的描述邏輯表示方法[J].計(jì)算機(jī)科學(xué),2010,(3).