当前位置: 首页 > news >正文

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>

相关文章:

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

背景 本文介绍Nginx中Lua模块使用方式&#xff0c;并结合案例进行介绍。案例介绍通过lua脚本提取HTTP请求头中的token字段&#xff0c;经过JWT校验并提取id和name信息&#xff0c;设置到http请求头中发向后段服务器。 默认情况下&#xff0c;Nginx自身不携带lua模块&#xff0…...

数据库设计三范式

目录 第一范式 第二范式 第三范式 数据库的设计范式&#xff0c;即数据库设计的原则&#xff1b; 在设计数据库时尽量遵守这三个条件&#xff0c;因为在实际的设计中&#xff0c;根据要求是空间换时间还是时间换空间来遵守范式&#xff1b; 第一范式 每一张表都必须有主键…...

VirtualBox创建共享磁盘

VirtualBox创建共享磁盘 目录 VirtualBox创建共享磁盘1、划分共享磁盘1.1、【管理】->【工具】->【虚拟介质管理】1.2、【创建】->【VDI&#xff08;VirtualBox 磁盘映像&#xff09;】->【下一步】1.3、【预先分配全部空间】->【下一步】1.4、【分配大小】->…...

2024年中职云计算实验室建设及云计算实训平台整体解决方案

随着信息技术的飞速发展&#xff0c;云计算作为新一代信息技术的核心&#xff0c;正逐步渗透到各行各业&#xff0c;成为推动数字化转型的重要力量。为了适应这一趋势&#xff0c;中职教育作为技能型人才培养的重要阵地&#xff0c;亟需加强云计算实验室建设与云计算实训平台的…...

[C++] C++11新增

一、列表初始化 C98&#xff1a; 在C98中&#xff0c;标准允许使用花括号{}对数组元素进行统一的列表初始值设定。 struct Simple1 {int _a;int _b; };//C98 int main() {int a1[] { 1,2,3,4,5,6 };int a2[7] { 0 };//本质是类型转换&#xff08;构造拷贝构造 -> 优化 …...

802.11 wireshark 抓包

80211 wireshark 抓包 前言配置 monitor软件配置wireshark 操作 前言 本人习惯使用 Omnipeek 抓包分析&#xff0c;所以 wireshark 的实验只讲到抓包完成。 Windows 环境采用 wireshark 抓包是比较麻烦的&#xff0c;因为支持在 Windows 环境中支持抓包的网卡并不多&#xff0…...

vscode 调试web后端

1、调试环境配置 一、安装python环境管理器 其中要先在vscode选择对应的python环境&#xff0c;最方便的是按照环境管理器后从中选择。其中在【externsions】里面安装python即可。 如下&#xff1a; 二、编写launch.json文件 其中如下&#xff1a; {// Use IntelliSense …...

JAVA默写单词小程序

编写一个记单词和默写单词两个功能的小程序 package com.lu.word;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString;Data AllArgsConstructor NoArgsConstructor ToString public class A {private String k;p…...

认知、情绪、情感、意志、人格

皮亚杰的认知发展阶段理论 个别差异与因材施教 情绪 情绪的理论 情感与情绪 意志 人格...

解析capl文件生成XML Test Module对应的xml工具

之前一直用的CAPL Test Module来写代码&#xff0c;所有的控制都是在MainTest()函数来实现的&#xff0c;但是有一次&#xff0c;代码都写完了&#xff0c;突然需要用xml的这种方式来实现&#xff0c;很突然&#xff0c;之前也没研究过&#xff0c;整理这个xml整的一身汗&#…...

Java中的反射是怎么回事?

反射的概念 《Java核心技术》中的定义是这样的&#xff1a;能够分析类能力的程序&#xff0c;就是反射 这就是一个概念&#xff0c;跟java中经常提的问题&#xff1a;对象是什么&#xff1f; 一类问题&#xff0c;简单来说就是将类创建对象的逻辑反过来&#xff0c;由对象获得…...

07 STM32寄存器开发基础-中断编程

文章目录 一、前言二、系列文章三、如何学习?四、单片机的中断知识点4.1 中断的概念4.2 中断服务函数中断服务函数与中断的关系中断服务函数的特点与编写要求中断服务函数的命名规则4.3 超声波测距项目里中断的使用思路超声波测距原理使用中断实现超声波测距硬件连接工作流程具…...

聚簇和非聚簇索引/Btree和B+tree

目录 1、聚簇&#xff08;聚集&#xff09;索引 &#xff08;1&#xff09;特点 &#xff08;2&#xff09;优点 &#xff08;3&#xff09;缺点 2、二级索引&#xff08;辅助索引、非聚簇索引&#xff09; 3、Btree&#xff08;平衡多路查找树&#xff09; 4、Btree 5…...

清华学姐熬夜肝了15天的软件测试面试题出炉(附答案)建议收藏!

一、Web自动化测试 1.Selenium中hidden或者是display &#xff1d; none的元素是否可以定位到&#xff1f; 不能,可以写JavaScript将标签中的hidden先改为0&#xff0c;再定位元素 2.Selenium中如何保证操作元素的成功率&#xff1f;也就是说如何保证我点击的元素一定是可以…...

Docker 安装指南

Docker 安装指南 文章目录 Docker 安装指南1. 卸载旧版2. 配置 Docker 的 YUM 库3. 安装 Docker4. 启动和校验5. 配置镜像加速6. 常见问题和解决方法7. 阅读和资源 Docker 是一个开源的容器化平台&#xff0c;能够让开发者打包应用及其依赖项到一个轻量级的、可移植的容器中。以…...

系统架构设计师 - 知识产权与标准化

知识产权与标准化 知识产权与标准化&#xff08;3分&#xff09;保护范围与对象 ★ ★ ★ ★法律法规 保护期限 ★ ★知识产权人确定 ★ ★ ★ ★侵权判断 ★ ★ ★ ★标准化&#xff08;了解&#xff09;★标准的分类标准的编号 大家好呀&#xff01;我是小笙&#xff0c;本章…...

【Python】Facebook开源时间序列数据预测模型Prophet

文章目录 一、简介二、项目的文件解读三、Prophet类主要方法和参数3.1 主要参数3.2 主要方法 四、用法示例 一、简介 Prophet 是由 Facebook 开发的一个开源工具&#xff0c;用于时间序列数据的预测。它特别适用于处理具有强季节性和趋势的时间序列数据&#xff0c;并且对节假…...

Spring 常用的三种拦截器详解

前言 在开发过程中&#xff0c;我们常常使用到拦截器来处理一些逻辑。最常用的三种拦截器分别是 AOP、 Interceptor 、 Filter&#xff0c;但其实很多人并不知道什么时候用AOP&#xff0c;什么时候用Interceptor&#xff0c;什么时候用Filter&#xff0c;也不知道其拦截顺序&am…...

微前端概念

微前端作用 大型应用程序的拆分独立的前端子应用降低程序复杂性&#xff0c;提高开发效率 微前端能力 js隔离css隔离元素隔离生命周期预加载数据通信应用跳转多层嵌套… 微前端实现方案 IframeSingle-spaQiankunMicro-app Iframe <iframe src"https://www.examp…...

FFmpeg实战 - 解复用解码

文章目录 前置知识音视频基础概念解复用、解码的流程分析FFMPEG有8个常用库 常见音视频格式的介绍aac格式介绍h264格式介绍flv格式介绍mp4格式介绍 FFmpeg解码解封装实战数据包和数据帧&#xff08;AVPacket/AVFrame&#xff09;AVPacket/AVFrame的引用计数问题API介绍注意事项…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序&#xff0c;无论是测试应用程序、搜寻漏洞还是收集情报&#xff0c;它们都能提升工作流程。 FoxyProxy 代理管理工具&#xff0c;此扩展简化了使用代理&#xff08;如 Burp…...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...

41道Django高频题整理(附答案背诵版)

解释一下 Django 和 Tornado 的关系&#xff1f; Django和Tornado都是Python的web框架&#xff0c;但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架&#xff0c;鼓励快速开发和干净、实用的设计。它遵循MVC设计&#xff0c;并强调代码复用。Django有…...

CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx

“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网&#xff08;IIoT&#xff09;场景中&#xff0c;结合 DDS&#xff08;Data Distribution Service&#xff09; 和 Rx&#xff08;Reactive Extensions&#xff09; 技术&#xff0c;实现 …...