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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50399.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Computer Analysis and Visualisation CITS2401

1. Outline In this project, we will continue from our Project 1 where we implemented a malicious credit card transaction detection system. But instead of iuww520iuww520​​​​​​​iuww520​​​​​​​iuww520​​​​​​​iuww520​​​​​​​iuww520​…

什么是海外云手机?海外云手机有什么用?

在跨境电商的浪潮中&#xff0c;如何高效引流成为了卖家们关注的焦点。近期&#xff0c;越来越多的卖家开始借助海外云手机&#xff0c;通过TikTok平台吸引流量&#xff0c;从而推动商品的海外销售。那么&#xff0c;究竟什么是海外云手机&#xff1f;海外云手机又能为跨境电商…

存储过程

1、概念 完成特定功能的sql语句的集合。把定义好的sql集合在一个特定的sql函数当中&#xff0c;每次执行调用函数即可&#xff0c;还可以实现传参的调用 2、作用 执行速度比sql语句执行速度更快&#xff0c;执行效率也更高 客户端可以随时调用发放&#xff0c;也可以随时修…

商家转账到零钱保姆级申请教程

大多数商家在申请微信支付的“商家转账到零钱”过程中都免不了遇到问题&#xff0c;更有不少商家因为屡次驳回严重耽误项目工期。为了帮助商户顺利开通该接口&#xff0c;根据我们上万次成功开通的经验整理这篇攻略以供参考&#xff1a; 一、前期准备 1. 确认主体资格&#xf…

跨境电商独立站术语盘点(一)独立站建站篇

跨境新手总是被一些跨境专业术语弄得头晕脑胀&#xff0c;不懂得查&#xff0c;查了又忘&#xff0c;忘了又得继续查…… 本期【跨境干货】&#xff0c;笔者特地为大家整理汇总了跨境电商独立站常用网站建站方面的专业术语&#xff0c;帮助你了解建站相关知识&#xff01;赶紧收…

安装python插件命令集合

安装python插件pyecharts库 pip install pyecharts -i https://pypi.tuna.tsinghua.edu.cn/simple 安装python插件pandas库 pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple PyCharm 中安装步骤&#xff1a;

数据结构之队列详解

1.队列的概念以及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFo(Frist in Frist out)的特性 入队列&#xff1a;进行插入才操作的一端称为队尾 出队列&#xff1a;进行删除操作的一…

谷粒商城实战笔记-编码经验积累

文章目录 1. 先理解需求&#xff0c;后写代码惨痛经历教训 2. 前后端都要校验惨痛经历教训 3&#xff0c;避免使用JOIN查询以提高性能4&#xff0c;用常量类代替魔法数字 1. 先理解需求&#xff0c;后写代码 惨痛经历 几年前&#xff0c;我所在的团队负责为开发一个在线预订系…

1比25万基础电子地图(广西版)

我们为你分享过四川、云南、江西、贵州、重庆、青海、西藏、新疆、甘肃、黑龙江、吉林、湖北、广东和内蒙古的1比25万基础电子地图&#xff0c;现在再为你分享广西版的电子地图。 如果你需要这些省份的1比25万基础电子地图&#xff0c;请在文末查看该数据的领取方法。 1比25万…

flutter开发实战-go_router使用

flutter开发实战-go_router使用 一、go_router介绍与特性 go_router是一个Flutter的第三方声明式路由插件&#xff0c;使用路由器API提供一个方便的、基于url的API&#xff0c;用于在不同屏幕之间导航。可以定义URL模式、使用URL导航、处理深度链接以及许多其他与导航相关的场…

【Spring Boot】Spring 的安全框架:Spring Security

Spring 的安全框架&#xff1a;Spring Security 1.Spring Security 初识1.1 核心概念1.2 认证和授权1.2.1 验证&#xff08;authentication&#xff09;1.2.2 授权&#xff08;authorization&#xff09; 1.3 模块 2.核心类2.1 Securitycontext2.2 SecurityContextHolder2.2.1 …

day51|99.岛屿数量, 100.岛屿的最大面积

99.岛屿数量 99. 岛屿数量 (kamacoder.com) DFS 思路没问题&#xff0c;内存超限了。 #include<iostream> #include<vector>using namespace std;int times 0;inline bool valid(int i, int j, const int &m, const int &n){return i > 0 &&am…

Python字符串处理技巧:一个小技巧竟然能省下你一半时间!

获取Pyhon及副业知识&#xff0c;关注公众号【软件测试圈】 效率翻倍的秘密&#xff1a;Python字符串操作的5个惊人技巧 在Python编程中&#xff0c;字符串处理在数据分析、Web开发、自动化脚本等多个领域都有广泛应用。Python提供了一系列强大的字符串处理函数&#xff0c;能够…

如何从零搭建一个动态网站

静态网站和动态网站的区别 静态网站和动态网站的本质区别在于内容是否在服务器端动态生成&#xff0c;以及是否有服务器端逻 辑处理用户请求和数据。 静态网站像是一本已经印刷好的书籍&#xff0c;而动态网站则像是根据读者需求即时编写和提供内容 的智能机器。 创建动态网…

前端工程化11-webpack常见插件

1、webpack的插件Plugin 刚才我们也讲解了下&#xff0c;我们对webpack路径的一个处理&#xff0c;处理的话包括别名的配置&#xff0c;模块是如何找到并加载的&#xff0c;总的来说到现在webpack这个配置到现在来说还是相当的麻烦的&#xff0c;但是目前来说我们讲的这些东西…

ssl证书过期,nginx更换证书以后仍然显示过期证书

记一次nginx部署异常 今天提示ssl证书过期了&#xff0c;然后重新申请了一个证书 反反复复折腾了一个上午&#xff0c;还更换了好几个平台&#xff0c;发现怎么更换都没用&#xff0c;百度上的解决方法都试过了&#xff0c;发现都没用&#xff0c;证书还是显示的原来那一个&…

前端工程化-vue项目创建

可以使用html、css、javascpript ,以及使用vue、axios等技术搭建前端页面&#xff0c;但效率低、结构乱。 实际前端开发&#xff1a; 前端工程化开发步骤&#xff1a; 一、环境准备 1.安装NodeJS2. 安装vue-cli 二、创建Vue项目 有两种方式创建&#xff0c;一般采用第二种图…

MMCV1.6.0之Runner/Hook/OptimizerHook(反向传播+参数更新)、Fp16OptimizerHook、自定义优化器与config设置

OptimizerHook 这段代码定义了一个名为 OptimizerHook 的类&#xff0c;它是一个用于优化器的自定义操作钩子。该钩子包含了一些用于梯度裁剪和检测异常参数的操作。这对于在深度学习训练过程中优化模型的性能和调试模型非常有用。 类的定义 OptimizerHook 类继承自 Hook&…

documents4j 将word转pdf文件,本地(Windows)测试没问题,部署到服务器(centos)报错

问题 报错如下&#xff1a; 代码 首先要保证你的Java代码没问题&#xff0c;可以参考下面代码 maven依赖 <!--documents4j--> <dependency><groupId>com.documents4j</groupId><artifactId>documents4j-local</artifactId><versi…

如果我是一名全能的工程师

今天的工作&#xff0c;让我深刻体会到为什么这两年&#xff0c;全栈这个词特别火&#xff0c;而且几乎每一家培训机构都在用全栈来推广他们的课程。 真正优秀的测试功能师&#xff0c;并不是单一的&#xff0c;能够从本身的功能里面找到多少BUG&#xff0c;或者说&#xff0c…