如何利用nginx+lua实现一个网页验证的功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何利用nginx+lua实现一个网页验证的功能相关的知识,希望对你有一定的参考价值。

参考技术A nginx的配置文件中有access_by_lua_file path;
可以在这里去做你需要先验证的东西,后面的path就是你的验证文件路径
比如你要验证用户是否登录,那你就可以写在这个文件里,然后在调用你接口之前,nginx会先调用这个文件验证

nginx安装luajwt模块,通过lua验证jwt实现蓝绿发布样例

文章目录


前言

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


一、基础组件下载

二、组件安装

1.luajit安装

编译

cd /opt/lua/
tar -zxvf v2.1-20210510.tar.gz
cd luajit2-2.1-20210510
make & make install

加载

ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/liblua-5.1.so.2
echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

配置环境变量

vi /etc/profile
#增加下面内容
export LUAJIT_INC=/usr/local/include/luajit-2.1
export LUAJIT_LIB=/usr/local/lib
#立刻生效
source /etc/profile

2.lua-nginx-module安装

cd /opt/lua/
tar -zxvf lua-nginx-module-0.10.20.tar.gz

3.lua-resty-core安装

cd /opt/lua/
tar -zxvf lua-resty-core-0.1.22.tar.gz
cd lua-resty-core-0.1.22
make install PREFIX=/usr/local/lua_core

4.lua-resty-lrucache安装

cd /opt/lua/
tar -zxvf lua-resty-lrucache-0.10.tar.gz
cd lua-resty-lrucache-0.10
make install PREFIX=/usr/local/lua_core

5.ngx_devel_kit安装

cd /opt/lua/
tar -zxvf ngx_devel_kit-0.3.1.tar.gz

6.nginx加载lua模块

nginx安装可参考往期文章:nginx安装部署详细手册

./configure --prefix=/opt/nginx/nginx  --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-openssl=/opt/openssl-1.1.1t --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/opt/nginx/ngx_devel_kit-0.3.2 --add-module=/opt/nginx/lua-nginx-module-0.10.22
make -j2
make install

nginx.conf配置文件中,http模块增加包依赖

lua_package_path "/usr/local/lua_core/lib/lua/?.lua;;";

增加lua测试代码

location /hello  
  default_type 'text/plain'; 
  content_by_lua 'ngx.say("hello, lua")'; 

检查配置
/opt/nginx/sbin/nginx -t
加载配置
/opt/nginx/sbin/nginx -s reload

访问192.168.19.110/hello,返回hello,lua,说明nginx集成lua成功

至此已经可以使用lua基本功能了,笔者因想使用lua实现jwt校验,所以后续还需要安装cjson和retry-http

7.lua-cjson安装

cd /opt/lua
tar -zxvf /lua-cjson-2.1.0.9.tar.gz
cd lua-cjson-2.1.0.9

修改Makefile,指定luajit

vi Makefile

将LUA_INCLUDE_DIR的值$(PREFIX)/include改为/usr/local/include/luajit-2.1

make && make install
cp cjson.so /usr/local/lib/lua/5.1/
chmod 755 /usr/local/lib/lua/5.1/cjson.so

8.lua-resty-string安装

cd /opt/lua/
tar -zxvf lua-resty-string-0.15.tar.gz
cd lua-resty-string-0.15
make install PREFIX=/usr/local/lua_core

9.lua-resty-jwt安装

cd /opt/lua/
tar -zxvf lua-resty-jwt-0.1.11.tar.gz
cp lua-resty-jwt-0.1.11/lib/resty/* /usr/local/lua_core/lib/lua/resty

10.lua-resty-hmac安装

cd /opt/lua/
tar -zxvf lua-resty-hmac-0.06.tar.gz
cp lua-resty-hmac-0.06/lib/resty/* /usr/local/lua_core/lib/lua/resty

至此,lua和jwt都集成完成,可以通过下面样例进行测试

nginx.conf配置文件中,http模块增加包依赖

lua_package_path "/usr/local/lua_core/lib/lua/?.lua;;";

增加lua测试代码

location /verify 
	default_type text/html;
	content_by_lua '
	local cjson = require "cjson"
	local jwt = require "resty.jwt"
	local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" ..
                    ".eyJmb28iOiJiYXIifQ" ..
                    ".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY"
	local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token)
	ngx.say(cjson.encode(jwt_obj))
    ';

手懒、网络不好的小伙伴可直接访问CSDN下载,包含全部基础组件(已验证兼容性)、nginx配置文件以及相关lua代码:点击访问下载页面


三、验证jwt中属性实现蓝绿发布样例

1.nginx配置修改

nginx.conf增加demo路由,并依赖自己写的jwttoken.lua

#demo
location /sign 
	access_by_lua_block 
    	local jwt = require "jwttoken"
		--type,value,redirectUrl(蓝绿类型,具体值,重定向地址)
		--1-按员工code蓝绿,2-按部门id蓝绿,3-按ip蓝绿
		jwt.auth("1","1001","http://www.baidu.com")
		ngx.say("hello world")
    

2.上传jwttoken.lua

将jwttoken.lua放到nignx所在服务器的/usr/local/lua_core/lib/lua/目录下
代码如下:

-- nginx-jwt.lua


local cjson = require "cjson"
local jwt = require "resty.jwt"

--your secret
local secret = "yoursecret"
--无需鉴权api清单
local no_need_token_api_list = '/v1/login'
local function ignore_url (val)
    for index, value in ipairs(no_need_token_api_list) do
        if (value == val) then
            return true
        end
    end

    return false
end

--获取客户端ip
local function get_client_ip()
    local headers = ngx.req.get_headers()
    local ip = headers["X-REAL-IP"] or headers["X_FORWARDED_FOR"] or ngx.var.remote_addr or "0.0.0.0"
    return ip
end



local M = 


function M.auth(type,value,redirectUrl)
    if ignore_url(ngx.var.request_uri) then
        return
    else
    end
	
	-- 根据ip判定蓝绿发布
	if(type == "3") then
	    local ip = get_client_ip()
		if(ip == value) then
			ngx.redirect(redirectUrl)
		else
			return
		end
	end
	
	
    -- require Authorization request header
    local auth_header = ngx.var.http_Authorization

    if auth_header == nil then
		ngx.log(ngx.DEBUG, "No Authorization header")
		return
        --ngx.exit(ngx.HTTP_UNAUTHORIZED)
    end

    -- require Bearer token
    local _, _, token = string.find(auth_header, "Bearer%s+(.+)")

    if token == nil then
		ngx.log(ngx.DEBUG, "Missing token")
		return
        --ngx.exit(ngx.HTTP_UNAUTHORIZED)
    end

    --decode_base64和后端保持一致
    local jwt_obj = jwt:verify(ngx.decode_base64(secret), token)

    --if jwt_obj.verified == false then
    --    ngx.log(ngx.ERR, "Invalid token: ".. jwt_obj.reason)
    --    ngx.status = ngx.HTTP_UNAUTHORIZED
    --    ngx.say(cjson.encode(jwt_obj))
    --    ngx.header.content_type = "application/json; charset=utf-8"
    --    ngx.exit(ngx.HTTP_UNAUTHORIZED)
    --end
	if jwt_obj.payload ~= nil then
	    ngx.log(ngx.DEBUG, cjson.encode(jwt_obj))
		
		-- 根据员工code判定蓝绿发布
		if(type == "1") then
			if jwt_obj.payload.emplCode == value then
				ngx.redirect(redirectUrl)
			else
				return
			end
		-- 根据部门id判定蓝绿发布
		elseif(type == "2") then
			if jwt_obj.payload.departId == value then
				ngx.redirect(redirectUrl)
			else
				return
			end
		end
	end

end

return M

完成后,重新加载nginx配置即可

加载配置
/opt/nginx/sbin/nginx -s reload

结尾

  • 感谢大家的耐心阅读,如有建议请私信或评论留言。
  • 如有收获,劳烦支持,关注、点赞、评论、收藏均可,博主会经常更新,与大家共同进步

以上是关于如何利用nginx+lua实现一个网页验证的功能的主要内容,如果未能解决你的问题,请参考以下文章

Nginx Lua的执行阶段

nginx安装luajwt模块,通过lua验证jwt实现蓝绿发布样例

nginx安装luajwt模块,通过lua验证jwt实现蓝绿发布样例

利用 nginx_lua 定制高效灵活的专属WAF

Golang实践录:使用gin框架实现转发功能:利用nginx转发

Golang实践录:使用gin框架实现转发功能:利用nginx转发