欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > Nginx系列-12 Nginx使用Lua脚本进行JWT校验

Nginx系列-12 Nginx使用Lua脚本进行JWT校验

2025/4/19 14:43:02 来源:https://blog.csdn.net/Sheng_Q/article/details/140570875  浏览:    关键词:Nginx系列-12 Nginx使用Lua脚本进行JWT校验

背景

本文介绍Nginx中Lua模块使用方式,并结合案例进行介绍。案例介绍通过lua脚本提取HTTP请求头中的token字段,经过JWT校验并提取id和name信息,设置到http请求头中发向后段服务器。
默认情况下,Nginx自身不携带lua模块,即不支持通过lua脚本进行功能扩展。需要在编译Nginx时手动引入lua模块,或者直接使用openresty,本文结合后者进行介绍。

1.openresty安装流程

1.1 安装包下载

wget https://openresty.org/download/openresty-1.25.3.1.tar.gz
tar -zxvf openresty-1.25.3.1.tar.gz
cd openresty-1.25.3.1/

1.2 配置

./configure --prefix=/usr/local/ewen/nginx --with-luajit --without-http_redis2_module --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-http_dav_module --with-http_mp4_module --with-http_v2_module 

由于案例不涉及使用Redis,因此可以在configure阶段通过–without-http_redis2_module以最小化安装。
执行结果如下:

platform: linux (linux)...Type the following commands to build and install:gmakegmake install

1.3 编译和安装

gmake
gmake install

1.4 案例测试

1.4.1 测试nginx正常工作

修改配置,添加一个location:

location /test {return 200 "test success";
}

运行nginx后:

[root@124 sbin]# curl http://localhost:8765/test
test success

1.4.2 测试nginx的lua插件正常工作

修改配置,添加一个location:

location /lua{content_by_lua 'ngx.say("<h1>HELLO,Lua</h1>")';
}

运行nginx后:

[root@124 sbin]# curl http://localhost:8765/lua
<h1>HELLO,Lua</h1>

2.lua介绍

参考: Lua使用方式介绍

3.http处理流程与lua模块

如Nginx系列-12 HTTP消息处理流程文中介绍,Nginx处理HTTP消息的流程可以分为如下11个阶段:
在这里插入图片描述
Lua模块可以参与rewrite、access、content、log阶段,流程和对应指令如下所示:
在这里插入图片描述

当使用lua生成HTTP响应内容时,在content阶段处理对应content_by_lua指令,而进行请求校验时在access阶段处理,对应access_by_lua_block或者access_by_lua_file指令。

4.案例介绍

案例介绍通过lua实现校验请求是否合法:请求头中带有合法的token, 则通过校验,否则返回401响应。
案例使用jwt解析token,因此需要引入jwt依赖(lua-resty-jwt库),包括hmac.lua、evp.lua、jwt.lua、jwt-validators.lua; hmac.lua来源于lua-resty-jwt\vendor\resty,evp.lua、jwt.lua、jwt-validators.lua来源于lua-resty-jwt\lib\resty.
可以通过access_by_lua_block块的形式或者access_by_lua_file文件形式引入lua文件,本文选择后者。

4.1 lua文件介绍

ewen.lua文件内容如下:

local white_url_list = {'/open'};-- 修改为自己的jwt密钥
public_key = "......";function startsWith(str, prefix)return string.sub(str, 1, string.len(prefix)) == prefix;
endlocal function exit_with_code_msg(code, msg)ngx.status = code;ngx.say(msg);ngx.exit(code);
endlocal function get_jwt_claims(token, public_key)local jwt = require("resty.jwt");local jwt_obj, err = jwt:verify(public_key, token);if not jwt_obj thenngx.say("Failed to verify JWT: ", err);return nil;endreturn jwt_obj["payload"];
endlocal function check_token_and_fill_head()local token = ngx.req.get_headers()["token"];if not token thenexit_with_code_msg(ngx.HTTP_UNAUTHORIZED, "401 Unauthorized: Token not found or invalid");endlocal payload = get_jwt_claims(token, public_key)if not payload thenexit_with_code_msg(ngx.HTTP_UNAUTHORIZED, "401 Unauthorized: Token not found or invalid");endngx.req.set_header("id", tostring(payload["id"]));ngx.req.set_header("name", tostring(payload["name"]));ngx.req.set_header("role", tostring(payload["role"]));
endlocal function need_check()for _, path in ipairs(white_url_list) doif startsWith(ngx.var.request_uri, path) thenreturn true;endendreturn false;
endif not need_check() thenngx.log(ngx.INFO, "JWT: " .. tostring(ngx.var.request_uri) .. "  check.");check_token_and_fill_head()
elsengx.log(ngx.INFO, "JWT: " .. tostring(ngx.var.request_uri) .. " not need to check.");
end

其中: ngx.status属性表示HTTP响应状态码;ngx.say方法用于设置响应体内容;ngx.exit(code)用于设置状态码并直接返回给客户端(结束请求);ngx.req.set_header方法用于设置请求头;require(“resty.jwt”)表示引入jwt库,之后jwt:verify方法用于对token进行JWT校验和Claim信息提取。

4.2 配置lua文件

在nginx.conf文件的http块或者server块中添加:

access_by_lua_file ./lua/jwt.lua;

4.3 案例测试

分别使用带token和不带token进行测试:

[root@124 conf]# curl -X GET http://localhost:8765/lua
401 Unauthorized: Token not found or invalid[root@124 conf]# curl -X GET -H "token:eyJhbGciOiJFUzI1NiJ9.eyJleHAiOjE3MTk5NzkyMjEsInV1aWQiOiI1Y2M4OGYwZC1hNGM5LTQyNTItODdkMC1hNzZkNmQxNzEzZTEiLCJncmFudFR5cGUiOiJzYWMiLCJidXNpbmVzcyI6ImVjaGF0OnVlOjE5NjAwMDEwMDk4Iiwic2NvcGUiOiJlY2hhdDpldHMtY2FyZXRha2VyIGVjaGF0OmV0cy1lbXBsb3llZSBlY2hhdDplZXAiLCJsb2dpbkluZm8iOiJlY2hhdDp1ZToxOTYwMDAxMDA5OCIsInVzZXJJZCI6LTEsInZlcnNpb24iOiIxLjAuMCJ9.augjMcBV7BKXOb4_JjIcZK4RGuYDoVf73DksFVR8o49F1yQWZiRn07ZH_xmt2RnJmpwRtg-fUmIGn7tNv3Q7Dg" http://localhost:8765/lua
<h1>HELLO,Lua</h1>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词