通过高性能网关OpenResty鉴权

zhx1994
zhx1994 2019-11-15 18:03
阅读需:0

        1.要先安装OpenResty的环境,安装地址 http://openresty.org/cn/installation.html

        2.配置nginx.conf

        location ^~ /business/ {

            default_type application/json;

            rewrite_by_lua_file /zzserver/acm/nginx/lua-code/error-service.lua;

            access_by_lua_file /zzserver/acm/nginx/lua-code/tr-jwt-auth.lua;

            proxy_pass http://localhost:8316/business/;

            body_filter_by_lua_file /zzserver/acm/nginx/lua-code/post-handle-body.lua;

        }


        post-handle-body.lua的内容

local userAccount = ngx.header["User-Account"]
if userAccount == nil then
    userAccount = ''
end 
if ngx.status == 500 then
    ngx.log(ngx.ERR, "failed request on current user:" .. userAccount)
elseif ngx.status == 409 then
    local resp_body = string.sub(ngx.arg[1], 1, 1000)
    ngx.log(ngx.ERR, "conflict request on current user:" .. userAccount .. "======response body:" .. resp_body)
end

       tr-jwt-auth.lua的内容

-- [function] verify jwt
secret_table = {
    WEB = "devwebf4e2e52034348f86b67cde581c0f9eb8",
        APP = "devappf4e2e52034348f86b67cde581c0f9eb8",
        MPP = "devmppf4e2e52034348f86b67cde581c0f9eb8",
    VPP = "devvppf4e2e52034348f86b67cde581c0f9eb8",
    VM  = "devvmf4e2e52034348f86b67cde581c0f9eb8",
    PMPP = "devpmppf4e2e52034348f86b67cde581c0f9eb8"
        }
function split(str, seperator)
    local sub_str_tab = {};  
    while (true) do          
        local pos = string.find(str, seperator);    
        if (not pos) then              
            local size_t = table.getn(sub_str_tab)  
            table.insert(sub_str_tab,size_t+1,str);  
            break;    
        end  
        local sub_str = string.sub(str, 1, pos - 1);                
        local size_t = table.getn(sub_str_tab)  
        table.insert(sub_str_tab,size_t+1,sub_str);  
        local t = string.len(str);  
        str = string.sub(str, pos + 1, t);     
    end      
    return sub_str_tab;
end

function error_response()
    local error_data = '{"code":401,"data":{},"message":"invalid token"}'
--  解决跨域问题
        ngx.header["Access-Control-Allow-Origin"] = ngx.var.http_origin
    ngx.header["Access-Control-Allow-Credentials"] = "true"
    ngx.status = ngx.HTTP_UNAUTHORIZED
    ngx.say(error_data)
end

function verify(secret,jwt_token)
    local cjson = require "cjson"
    local jwt = require "resty.jwt"
    local jwt_obj = jwt:verify(secret,jwt_token)
    local json = require "resty.json"
    if jwt_obj.verified then
        -- 提取token中用户账号添加到header中
        local result = cjson.encode(jwt_obj.payload.sub)
        local data = cjson.decode(result)
        ngx.header["User-Account"] = json.decode(data)["phone"]
    end
    return jwt_obj.verified
end

local req_method = ngx.var.request_method
local token = ngx.req.get_headers()["token"]
ngx.header["User-Account"] = ''
-- 解决前端本地调用服务器接口时涉及跨域时,会先发送options请求来验证接口是否可用,放行这类请求方式的接口不做jwt校验
if req_method == 'OPTIONS' then
    return
end

-- 自定义的一些不需要做jwt验证的接口的正则匹配
-- \w或者\d都需要对\进行转义,此外如果正则在nginx的配置配置文件中写lua的正则,则需要再做一层转义即变为\\\\w
local regex = "\\w+/(\\d+/appDeviceInfo$|common/oss/tokens$|share|demo|access/vm/\\w+|notify|backfill$|captcha.jpg$|tokens/reset$|login$|logout$|excels$|\\d+/pdf$|appUpgrades$|messages$|registers$|passwords|energy)"
local m = ngx.re.match(ngx.var.uri, regex)
if m then
    return
end

-- 校验jwt
if token == nil or token == '' then
    error_response()
    return
end
local str_list = split(token,"|")
local sys_channel = str_list[1]
local jwt_token = str_list[2]
local secret = secret_table[sys_channel]
local isPass = verify(secret,jwt_token)

if not isPass then
    error_response()
end


评论
  • 消灭零回复