小編給大家分享一下Openresty如何實(shí)現(xiàn)的網(wǎng)關(guān)權(quán)限控制,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
榆中網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,榆中網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為榆中上1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的榆中做網(wǎng)站的公司定做!
本小節(jié)采用了以下的技術(shù)棧:
Openresty(lua+nginx)
MySQL
redis
cjson
用戶請(qǐng)求經(jīng)過(guò)nginx,nginx的openresty的模塊通過(guò)攔截請(qǐng)求來(lái)進(jìn)行權(quán)限判斷
openresty的access_by_lua_file模塊,進(jìn)行了一系列的判斷
用戶的請(qǐng)求是否為白名單uri,如果為白名單uri,則直接通過(guò)驗(yàn)證,進(jìn)入下一個(gè)驗(yàn)證環(huán)節(jié)content_by_lua_file,這個(gè)環(huán)節(jié)直接打印一句話:“恭喜,請(qǐng)求通過(guò)。”
如果用戶請(qǐng)求不為白名單url,則需要取出請(qǐng)求header中的token,如果請(qǐng)求的header不存在token,則直接返回結(jié)果401,無(wú)權(quán)限訪問(wèn)。
如果用戶請(qǐng)求的uri的請(qǐng)求頭包含token ,則取出token,解密token取出用戶id
根據(jù)取出的userid去查詢數(shù)據(jù)庫(kù)獲取該用戶的權(quán)限,如果權(quán)限包含了該請(qǐng)求的uri,請(qǐng)求可以通過(guò),否則,請(qǐng)求不通過(guò)。
請(qǐng)求如果通過(guò)access_by_lua_file模塊,則進(jìn)入到content_by_lua_file模塊,該模塊直接返回一個(gè)字符串給用戶請(qǐng)求,在實(shí)際的開(kāi)發(fā)中,可能為路由到具體的應(yīng)用程序的服務(wù)器。
驗(yàn)證流程圖如下所示:
vim /usr/example/example.conf ,加上以下的配置:
location / { default_type "text/html"; access_by_lua_file /usr/example/lua/api_access.lua; content_by_lua_file /usr/example/lua/api_content.lua; }
以上的配置表示,要不符合已有l(wèi)ocation路徑的所有請(qǐng)求,將走這個(gè)location為/ 的路徑。符合這個(gè)location的請(qǐng)求將進(jìn)入 access_by_lua_file和 content_by_lua_file的模塊判斷。
vim /usr/example/lua/access_by_lua_file ,加上以下代碼:
local tokentool = require "tokentool" local mysqltool = require "mysqltool" function is_include(value, tab) for k,v in ipairs(tab) do if v == value then return true end end return false end local white_uri={"/user/login","/user/validate"} --local user_id = ngx.req.get_uri_args()["userId"] --獲取header的token值 local headers = ngx.req.get_headers() local token=headers["token"] local url=ngx.var.uri if ( not token) or (token==null) or (token ==ngx.null) then if is_include(url,white_uri)then else return ngx.exit(401) end else ngx.log(ngx.ERR,"token:"..token) local user_id=tokentool.get_user_id(token) if (not user_id) or( user_id ==null) or ( user_id == ngx.null) then return ngx.exit(401) end ngx.log(ngx.ERR,"user_id"..user_id) local permissions={} permissions =tokentool.get_permissions(user_id) if(not permissions)or(permissions==null)or( permissions ==ngx.null) then permissions= mysqltool.select_user_permission(user_id) if permissions and permissions ~= ngx.null then tokentool.set_permissions(user_id,permissions) end end if(not permissions)or(permissions==null)or( permissions ==ngx.null) then return ngx.exit(401) end local is_contain_permission = is_include(url,permissions) if is_contain_permission == true then -- ngx.say("congratuation! you have pass the api gateway") else return ngx.exit(401) end end
在上述代碼中:
is_include(value, tab),該方法判斷某個(gè)字符串在不在這個(gè)table中。
white_uri={“/user/login”,”/user/validate”} 是一個(gè)白名單的列表。
local headers = ngx.req.get_headers()從請(qǐng)求的uri的請(qǐng)求頭獲取token
is_include(url,white_uri)判斷該url是否為白名單url
local user_id=tokentool.get_user_id(token)根據(jù)token獲取該token對(duì)應(yīng)的用戶的user_id,在常見(jiàn)情況下,是根據(jù)token解析出user_id,但在不同的語(yǔ)言加密和加密token存在鹽值不一樣的情況,比較麻煩,所以我偷了個(gè)懶,直接存了redis,用戶登錄成功后存一下。
permissions =tokentool.get_permissions(user_id)根據(jù)user_id
從redis獲取該用戶的權(quán)限。
permissions= mysqltool.select_user_permission(user_id)如果redis沒(méi)有存該用戶的權(quán)限,則從數(shù)據(jù)庫(kù)讀。
tokentool.set_permissions(user_id,permissions),將從數(shù)據(jù)庫(kù)中讀取的權(quán)限點(diǎn)存在reddis中。
local is_contain_permission = is_include(url,permissions),判斷該url 在不在該用戶對(duì)應(yīng)的權(quán)限列表中。
如果所有的判斷通過(guò),則該用戶請(qǐng)求的具有權(quán)限訪問(wèn),則進(jìn)入content_by_lua_file模塊,直接在這個(gè)模塊給請(qǐng)求返回“congratulations! you have passed the api gateway”。
vim /usr/example/lua/api_content.lua ,添加以下內(nèi)容:
ngx.say("congratulations!"," you have passed ","the api gateway") ----200狀態(tài)碼退出 return ngx.exit(200)
打開(kāi)瀏覽器訪問(wèn)http://116.196.177.123/user/login,瀏覽器顯示:
congratulations! you have passed the api gateway
/user/login這個(gè)url 在白名單的范圍內(nèi),所以它是可以通過(guò)權(quán)限驗(yàn)證的。
打開(kāi)瀏覽器訪問(wèn)http://116.196.177.123/user/sss,顯示以下內(nèi)容:
401 Authorization Required
openresty/1.11.2.4
在redis中添加一對(duì)key-value,key為token_forezp,value為1,即token_forezp對(duì)應(yīng)的用戶的id為1.
/usr/servers/redis-3.2.6 src/redis-cli set token_forezp 1
初始化以下的sql腳本,即給用戶id為1的用戶關(guān)聯(lián)角色,角色并關(guān)聯(lián)權(quán)限:
INSERT INTO `permission` VALUES ('1', '/user/orgs'); INSERT INTO `role` VALUES ('1', 'user'); INSERT INTO `role_permission` VALUES ('1', '1', '1'); INSERT INTO `user` VALUES ('1', 'forezp'); INSERT INTO `user_role` VALUES ('1', '1', '1');
用postman請(qǐng)求,在請(qǐng)求頭中加入token,值為token_forezp,請(qǐng)求結(jié)果如下:
以上是“Openresty如何實(shí)現(xiàn)的網(wǎng)關(guān)權(quán)限控制”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
文章標(biāo)題:Openresty如何實(shí)現(xiàn)的網(wǎng)關(guān)權(quán)限控制
網(wǎng)站地址:http://muchs.cn/article28/ihcscp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、網(wǎng)站改版、響應(yīng)式網(wǎng)站、網(wǎng)站設(shè)計(jì)公司、移動(dòng)網(wǎng)站建設(shè)、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)