欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

nginx+lua(openresty)實(shí)現(xiàn)黑/白名單權(quán)限控制的示例

 更新時間:2024年09月12日 10:14:37   作者:lgq2016  
本文介紹了如何使用Openresty進(jìn)行權(quán)限控制和灰度發(fā)布,具體通過定時器定期更新黑名單數(shù)據(jù),進(jìn)行用戶過濾和權(quán)限管控,具有一定的參考價(jià)值,感興趣的可以了解一下

 openresty在nginx基礎(chǔ)上集成了很多功能,比如可以直接調(diào)用redis,mysql,http接口等服務(wù),比較流行的網(wǎng)關(guān)kong就是通過openresty實(shí)現(xiàn)的。日常開發(fā)和運(yùn)維離不開nginx,實(shí)現(xiàn)稍微復(fù)雜的功能:簡單權(quán)限控制,灰度發(fā)布等就可以通過openresty實(shí)現(xiàn)。

本文通過openresty定時器定期請求http接口獲取更新的黑名單數(shù)據(jù),過濾用戶并做進(jìn)一步的判斷(結(jié)合實(shí)際的業(yè)務(wù)需求)進(jìn)行權(quán)限管控。話不多說,直接上nginx.conf代碼如下。

user  root;
worker_processes  auto;
worker_cpu_affinity auto;

error_log  logs/error.log  error;
worker_rlimit_nofile 30000;
pid        logs/nginx.pid;
events {
    use epoll;
    worker_connections  65535;
}

http {
   #include       mime.types;
    default_type  application/octet-stream;
    sendfile    on;
    tcp_nopush  on;
    server_tokens off;
    underscores_in_headers on;
    keepalive_timeout  10;
    send_timeout 60;
    include /usr/local/nginx/conf/online/*.conf;
    #下面四行和lua相關(guān),重點(diǎn)看一下
    lua_shared_dict portalCache 10m;#多進(jìn)程共享內(nèi)存變量
    lua_shared_dict commonCache 1m;
    init_by_lua_file /home/www/example/lua/api_init.lua;#初始化全局變量
    init_worker_by_lua_file /home/www/example/lua/api_timer.lua; #啟動定時器定期調(diào)用接口
    upstream portalBackend {
        server xxx weight=3;
        server xxx weight=1;
    }
    upstream labelBackend {
        server xxx;
        server xxx;
    }
    upstream portalBackendOnQlikTicket {
       server xxx;
       server xxx;
    }
    upstream portalClient {
        server xxx;
        server xxx;
    }
    upstream portalAdmin {
        server xxx;
        server xxx;
    }
    upstream labelFrontend {
        server xxx;
        server xxx;
    }
    upstream bigScreen {
        server xxx;
        server xxx;
    }
    upstream mobile {
        server xxx;
        server xxx;
    }
    upstream portalMobile {
        server xxx;
        server xxx;
    }

    server {
        listen       80;
        server_name  localhost hportal-uat.hikvision.com.cn;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location / {
                proxy_pass http://portalClient;
                proxy_redirect    off;
                proxy_set_header  Host $host;
                proxy_set_header  X-real-ip $remote_addr;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;

            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPT                                                                             IONS';
            add_header Access-Control-Allow-Credentials 'true';
            add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Aliv                                                                             e,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Autho                                                                             rization,Origin,Accept';
        }
        location /ptclient {
                proxy_pass http://portalClient/ptclient;
                proxy_redirect    off;
                proxy_set_header  Host $host;
                proxy_set_header  X-real-ip $remote_addr;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
                    add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPT                                                                             IONS';
            add_header Access-Control-Allow-Credentials 'true';
            add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Aliv                                                                             e,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Autho                                                                             rization,Origin,Accept';
        }
        location /ptadmin {
                proxy_pass http://portalAdmin/ptadmin;
                proxy_redirect    off;
                proxy_set_header  Host $host;
                proxy_set_header  X-real-ip $remote_addr;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /api/ {
         #...............error.log......notice
                rewrite_log on;
        #...............
                rewrite ^/api/(.*)$ /$1 break;
                proxy_pass http://portalBackend;
                proxy_http_version 1.1;
                proxy_redirect    off;
                proxy_set_header  Host $host;
                proxy_set_header Origin '';
                proxy_set_header  X-real-ip $remote_addr;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                add_header Access-Control-Allow-Origin *;
                add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE,                                                                              OPTIONS';
                add_header Access-Control-Allow-Credentials 'true';
                add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-                                                                             Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,A                                                                             uthorization,Origin,Accept';
        }

	location /api/checkVmPermission {
            default_type text/html;
            access_by_lua_file /home/www/example/lua/api_access.lua;
        }

	location /api/test {
		content_by_lua_block {
			local portalCache = ngx.shared.portalCache;
			ngx.say(portalCache:get("userAccountList"))
		}
	}

        location @router{
            rewrite ^.*$ /index.html last;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

#上述代碼段中的接口只需要關(guān)注 /api/checkVmPermission和/api/test 即可。

api_init.lua代碼如下所示:

json = require "cjson.safe"
http = require("resty.http")
interval = 60
portalCache = ngx.shared.portalCache
ipList = {"xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx"......}
portalCache:set("flag", true)
portalCache:set("ipList", json.encode(ipList))

api_timer.lua代碼如下所示:

local function newClient()
	local httpC = http.new()
        return httpC
end
local handler = function (premature)	
    local httpc = newClient()
    local resp,err = httpc:request_uri("http://10.10.10.10:8080", {
        method = "GET",
        path = "/xxx/xxx",
		--請求的校驗(yàn)字段
        headers = {
                ["VM_HEADER"] = "xxxxx"
        }
    })
	--array為類型table,需要序列化之后才能存入portalCache
    local array = json.decode(resp.body).data
    portalCache:set("userAccountList", json.encode(array))
end
--只有一個進(jìn)程負(fù)責(zé)定時任務(wù)
if 0 == ngx.worker.id() then
    local ok, err = ngx.timer.every(interval, handler)
    if not ok then
       log(ERR, "failed to get userAccountList: ", err)
       return
    end
end

api_access.lua代碼如下所示:

function account_is_include(value, tab)
    --string 轉(zhuǎn)table
   local table = json.decode(tab)
   for k,v in ipairs(table) do
      if string.lower(v) == string.lower(value) then
           return true
       end
    end
    return false
end

function ip_is_include(value, tab)
   for k,v in ipairs(tab) do
      if string.find(value, v) ~= nil then
           return true
      end
   end
   return false
end

local function newClient()
        local httpC = http.new()
        return httpC
end
local handler = function (premature)
    local httpc = newClient()
    local resp,err = httpc:request_uri("http://xx.xx.xx.xx:xxxx", {
        method = "GET",
        path = "/xxx/xxx",
        headers = {
                ["VM_HEADER"] = "xxx"
        }
    })
    local array = json.encode(json.decode(resp.body).data)
    portalCache:set("userAccountList", array)
end
--nginx啟動時先調(diào)用一次
if portalCache:get("flag") then
   portalCache:set("flag", false)
   handler()
end

check_userAccount = portalCache:get("userAccountList")
check_ip = json.decode(portalCache:get("ipList"))
if nil == check_userAccount or nil == check_ip then
   return ngx.exit(500)
end

local headers = ngx.req.get_headers()
local userAccount = headers["userAccount"]
if userAccount == nil then
   return ngx.exit(401)
end
if account_is_include(userAccount, check_userAccount) then
    local clientIP = headers["x-forwarded-for"]
    if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
      	 clientIP = headers["Proxy-Client-IP"]
    end
    if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
         clientIP = headers["WL-Proxy-Client-IP"]
    end
    if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
         clientIP = ngx.var.remote_addr    
    end
        -- ...............IP......IP,..IP..','..
    if clientIP ~= nil and string.len(clientIP) >15  then
         local pos  = string.find(clientIP, ",", 1)
       	 clientIP = string.sub(clientIP,1,pos-1)
    end
    if clientIP == nil then
	return ngx.exit(500)
    end
    if ip_is_include(clientIP, check_ip) then
	return ngx.say(userAccount .. " " .. "Welcome to Hportal! (VM-IP:" .. clientIP ..")")
    else
        ngx.status = 403
        ngx.say("Error! Restricted permissions! Your IP is " .. clientIP .. ". Make sure your IP is within this range: " .. json.encode(check_ip))
    end
else
   ngx.say(userAccount .. " " .. "Welcome to Hportal!")
end

最后實(shí)現(xiàn)效果如下所示:

常見問題匯總:

1.init_worker_by_lua_file error: /usr/local/openresty/lualib/resty/http.lua:133: API disabled in the context of init_worker_by_lua*

stack traceback:
        [C]: in function 'ngx_socket_tcp'
        /usr/local/openresty/lualib/resty/http.lua:133: in function 'new'
        /home/www/example/lua/api_timer.lua:6: in function 'newClient'
        /home/www/example/lua/api_timer.lua:21: in function 'getUserAccountTask'
        /home/www/example/lua/api_timer.lua:35: in main chunk

答:在init_worker_by_lua...中不能直接調(diào)報(bào)表http的函數(shù),必須在定時器里面調(diào)用。

2.json.decode(resp.body).data (table類型)無法直接放入公共緩存變量的value中

答:set時需要將table轉(zhuǎn)為string,get時再轉(zhuǎn)為table。

3. 如何訪問http接口

答:推薦使用httpc,openresty本身不支持,需要在/usr/local/openresty/lualib/resty目錄下引入以下三個文件:https://github.com/ledgetech/lua-resty-http/tree/master/lib/resty

4.如何獲取請求真實(shí)ip地址?

local headers=ngx.req.get_headers()
local clientIP = headers["x-forwarded-for"]
if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
      clientIP = headers["Proxy-Client-IP"]
end
if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
      clientIP = headers["WL-Proxy-Client-IP"]
end
if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
      clientIP = ngx.var.remote_addr    
end
-- 對于通過多個代理的情況,第一個IP為客戶端真實(shí)IP,多個IP按照','分割
if clientIP ~= nil and string.len(clientIP) >15  then
      local pos  = string.find(clientIP, ",", 1)
      clientIP = string.sub(clientIP,1,pos-1)
end

 到此這篇關(guān)于nginx+lua(openresty)實(shí)現(xiàn)黑/白名單權(quán)限控制的示例的文章就介紹到這了,更多相關(guān)nginx 黑/白名單權(quán)限控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mac M1 Nginx 配置多站點(diǎn)的實(shí)現(xiàn)

    Mac M1 Nginx 配置多站點(diǎn)的實(shí)現(xiàn)

    這篇文章主要介紹了Mac M1 Nginx 配置多站點(diǎn)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 開發(fā)環(huán)境服務(wù)器vs生產(chǎn)環(huán)境服務(wù)器:開發(fā)與生產(chǎn)須分明詳解

    開發(fā)環(huán)境服務(wù)器vs生產(chǎn)環(huán)境服務(wù)器:開發(fā)與生產(chǎn)須分明詳解

    開發(fā)環(huán)境服務(wù)器(如Vite)和生產(chǎn)環(huán)境服務(wù)器(如Nginx和Node.js)在職責(zé)和工作方式上存在顯著差異,開發(fā)環(huán)境服務(wù)器專注于快速開發(fā)和調(diào)試,而生產(chǎn)環(huán)境服務(wù)器則強(qiáng)調(diào)穩(wěn)定性和高并發(fā)處理,Vite適合開發(fā)環(huán)境,而Nginx和Node.js更適合生產(chǎn)環(huán)境
    2025-01-01
  • nginx修改默認(rèn)端口方法圖文詳解

    nginx修改默認(rèn)端口方法圖文詳解

    我們都知道nginx 默認(rèn)使用80端口,有時候我們希望nginx運(yùn)行在其他端口,下面這篇文章主要給大家介紹了關(guān)于nginx修改默認(rèn)端口的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • nginx指定conf文件路徑的方法詳解

    nginx指定conf文件路徑的方法詳解

    在使用?Nginx?時,有時需要指定配置文件(nginx.conf)的路徑,這篇文章為大家整理了一些常用的方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • 教你如何快速在CentOS7中安裝Nginx

    教你如何快速在CentOS7中安裝Nginx

    今天我們就只圖快不圖細(xì)的講解一下如何在CentOS7系統(tǒng)下快速安裝Nginx,本文通過圖文并茂的形式給大家展示,感興趣的朋友一起看看吧
    2021-09-09
  • Nginx實(shí)現(xiàn)請求的超時自動重試的方法示例

    Nginx實(shí)現(xiàn)請求的超時自動重試的方法示例

    在當(dāng)今數(shù)字化的快節(jié)奏世界中,我們的網(wǎng)絡(luò)應(yīng)用就像是繁忙的交通樞紐,每天都要處理海量的請求,我們需要一種像“備用路線”一樣的機(jī)制,也就是請求的超時自動重試,本文就給大家介紹了Nginx?中怎樣實(shí)現(xiàn)請求的超時自動重試,需要的朋友可以參考下
    2024-07-07
  • 關(guān)于Nginx 命令行控制的問題

    關(guān)于Nginx 命令行控制的問題

    Nginx 是一個高性能的 Web 服務(wù)器,從 2001 年發(fā)展至今,由于 Nginx 對硬件和操作系統(tǒng)內(nèi)核特性的深度挖掘,使得在保持高并發(fā)的同時還能夠保持高吞吐量,這篇文章主要介紹了Nginx 命令行控制,需要的朋友可以參考下
    2022-10-10
  • upstream模塊中常用options選項(xiàng)講解

    upstream模塊中常用options選項(xiàng)講解

    這篇文章主要為大家介紹了upstream模塊中常用options選項(xiàng)講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Nginx配置參數(shù)中文說明詳解(負(fù)載均衡與反向代理)

    Nginx配置參數(shù)中文說明詳解(負(fù)載均衡與反向代理)

    最近在看高性能Linux服務(wù)器構(gòu)建實(shí)戰(zhàn)的Nginx章節(jié),對其nginx介紹的非常詳細(xì),現(xiàn)把經(jīng)常用到的Nginx配置參數(shù)中文說明摘錄和nginx做負(fù)載均衡的本人真實(shí)演示實(shí)例抄錄下來以便以后查看
    2020-03-03
  • Nginx跨域使用字體文件的配置方法

    Nginx跨域使用字體文件的配置方法

    這篇文章主要介紹了Nginx跨域使用字體文件的配置方法,使用HttpHeadersModule模塊實(shí)現(xiàn),需要的朋友可以參考下
    2014-06-06

最新評論