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

如何在 Nginx Lua 脚本中实现 HMAC 签名验签 API 鉴权?

在 Nginx 中实现 HMAC 验签,最稳妥的方案是基于 OpenResty 搭配 lua-resty-string 库,在 access_by_lua 阶段完成计算与比对。这适合需要高性能网关鉴权的场景。

先说结论:使用 OpenResty 的 lua-resty-string 模块处理加密运算,配合 access_by_lua 拦截请求,是兼顾性能与维护性的做法。

  • 先判断:确认 Nginx 已编译 lua 模块且可加载 resty 库
  • 优先做:在 Lua 脚本中统一构建签名字符串,避免前后端规则不一致
  • 再验证:通过 curl 携带签名头请求,观察日志与状态码

完整配置示例

以下配置展示了如何在 http 块加载模块,并在 location 中集成验签逻辑。注意密钥不要硬编码,生产环境建议使用环境变量或配置中心。

http {lua_package_path "/usr/local/openresty/lualib/?.lua;;";server {location /api/ {access_by_lua_block {-- 引入依赖local hmac = require "resty.hmac"local str = require "resty.string"local ngx_var = ngx.var-- 1. 获取请求头参数,防止 nil 报错local timestamp = ngx_var.http_x_timestamplocal client_sign = ngx_var.http_x_signatureif not timestamp or not client_sign thenngx.log(ngx.ERR, "missing timestamp or signature")return ngx.exit(403)end-- 2. 检查时间戳过期 (假设允许 5 分钟误差)local now = ngx.time()if math.abs(now - tonumber(timestamp)) > 300 thenngx.log(ngx.ERR, "timestamp expired")return ngx.exit(403)end-- 3. 构建待签名字符串 (必须与客户端一致)local str_to_sign = ngx_var.request_method .. ":" .. ngx_var.uri .. ":" .. timestamplocal secret = "your_secret_key" -- 生产环境请替换为动态获取-- 4. 计算 HMAC SHA256local hm = hmac:new(secret, hmac.ALG_SHA256)hm:update(str_to_sign)local sign_binary = hm:final()-- 5. 转为 hex 并比对 (关键步骤:binary 转 hex)local server_sign = str.to_hex(sign_binary)if server_sign ~= client_sign thenngx.log(ngx.ERR, "signature mismatch")return ngx.exit(403)end}proxy_pass http://backend;}}
}

客户端签名生成脚本

为了验证 Nginx 配置,可以使用以下 Python 脚本生成合法的签名头。确保待签名字符串拼接规则与 Nginx 端完全一致。

import hmac
import hashlib
import timesecret = "your_secret_key"
timestamp = str(int(time.time()))
method = "GET"
uri = "/api/test"# 构建待签名字符串
str_to_sign = f"{method}:{uri}:{timestamp}"# 计算 HMAC SHA256
signature = hmac.new(secret.encode(), str_to_sign.encode(), hashlib.sha256).hexdigest()print(f"X-Timestamp: {timestamp}")
print(f"X-Signature: {signature}")
# 使用示例:curl -H "X-Timestamp: {timestamp}" -H "X-Signature: {signature}" http://your-domain.com/api/test

验证与排查

使用 curl 命令模拟携带签名的请求,并观察 Nginx 错误日志。

curl -H "X-Timestamp: 1700000000" -H "X-Signature: 计算出的 hex 值" http://your-domain.com/api/test

观察 Nginx 错误日志(通常位于 /usr/local/openresty/nginx/logs/error.log)。如果验签失败,应看到自定义的日志记录;如果验签成功,请求应正常返回 200 状态码。也可以故意篡改签名值,确认是否返回 403。

常见坑

  • 时间同步:客户端与服务端时间偏差过大会导致验签失败。通常允许±5 分钟误差,需在 Lua 脚本中做时间差判断。
  • 字符串构建规则:前后端构建“待签名字符串”的顺序必须完全一致(例如参数是否排序、是否包含查询字符串)。一致性是生效的前提。
  • 密钥安全:密钥不能明文写在代码库里。如果 Nginx 配置被泄露,密钥也会泄露。建议结合 IP 白名单或定期轮换密钥。
  • HTTPS 强制:签名本身不加密传输内容。如果通过 HTTP 传输,签名和密钥可能被中间人截获。务必在 Nginx 层强制跳转 HTTPS。

参考来源

  • OpenResty 官方文档,页面标题:OpenResty® - Official Site,URL:https://openresty.org/
  • lua-resty-string 项目仓库,页面标题:openresty/lua-resty-string,URL:https://github.com/openresty/lua-resty-string

原文链接:https://www.zjcp.cc/ask/11355.html

http://www.jsqmd.com/news/835014/

相关文章:

  • 西安除甲醛公司怎么选?三大硬核标准识破“伪直营”套路 - 博客湾
  • MindSpore 与 PyTorch 在昇腾上的开发
  • # 2026年GEO优化服务商推荐:按企业需求场景选择合作伙伴的决策指南 - 科技焦点
  • 郑州除甲醛公司避坑:直营、伪直营与加盟的本质区别 - 博客湾
  • 苏州除甲醛公司怎么选:别被“百城直营”四个字带走节奏 - 博客湾
  • 昇腾算子开发体系
  • 《觉醒时刻:AI Agent引爆企业效率革命》第一章
  • 2026年|Turnitin查出AIGC率爆表?3个亲测有效方法教你高效去AI痕迹,附官方检测报告! - 降AI实验室
  • 苏州除甲醛真相:别被“全国直营”话术忽悠,这三类公司才靠谱 - 博客湾
  • 昇腾分布式训练策略
  • 金华木门厂家哪家好?2026年本地源头与全国品牌深度对比 - Amonic
  • 芝柏官方售后网点2026年5月【亲测】报告:实地【数据验证】与【避坑指南】 - 亨得利官方服务中心
  • 2026年GEO优化公司选型指南:五家靠谱服务商深度分析 - 科技焦点
  • 昇腾TBE张量加速引擎
  • 南京除甲醛公司的水有多深?百城直营基本都是骗子 - 博客湾
  • 杭州奢侈品包包回收哪家靠谱?本地门店深度测评 热门款二手回收报价行情 - 博客湾
  • 实木门哪家厂家好?2026年实木门厂家实力盘点与选择指南 - Amonic
  • 兼容车牌摄像头 和 tplink 摄像头的sdk开发包 集成
  • 宁波慈溪余姚二手奢侈品包回收怎么选不踩坑?本地正规门店深度测评与出手攻略 - 博客湾
  • 亲历2026年5月雷达官方售后网点真实体验:避坑指南与老司机分享(含迁址/新开)实地考察・多方验证 - 亨得利官方服务中心
  • 昇腾模型推理与DVPP媒体处理
  • 2026防腐压力传感器五大排行,广东犸力品质过硬更专业 - 品牌速递
  • 2026年Openai搜索结果优化服务商TOP3权威测评:谁能让中国品牌在ChatGPT搜索中不再隐形? - 博客湾
  • 2026扭力传感器厂家,广东犸力匠心制造信得过 - 品牌速递
  • 昇腾软件栈全景
  • 豆包AI优化系统实力评测:三大GEO服务商排名的深度解析与选择指南 - 博客湾
  • 重庆除甲醛公司怎么选?看懂这5个指标,避开90%的坑 - 博客湾
  • 重庆除甲醛公司优劣评判指南:全国直营vs本地伪直营深度解析 - 博客湾
  • 2026转矩传感器十大品牌,广东犸力实力出圈获一致好评 - 品牌速递
  • AI 编程不缺代码能力,缺的是这套 Agent Skills 工程能力库