nginx 记录完整的 request 及 response

前言

在开发的过程中, 经常会有抓包的需求, 查看请求体和响应体. 使用 charles 等抓包工具会遇到一些麻烦, 如:

  1. localhost 请求无法捕获
  2. 有些工具配置代理比较麻烦, 如docker配置代理后需要重启
  3. https协议需要代理端配置证书进行解密, 比较麻烦

于是, 我就在想, 能否直接在服务端将所有的请求体和响应体打印出来, 不就完美解决这个问题了么?

一般来说, 通过nginx代理请求, 所有的请求都过nginx, nginx自身也有https的私钥, 会进行解密.

那么问题来了, 如何通过nginx打印请求呢?

中间探索的过程就不提了, 直接上结果.

lua打印

这里直接使用openresty/openresty镜像了, 当然如果直接使用nginx编译lua插件也是可以的.

在配置文件中添加如下lua脚本以打印完整请求内容:

lua 复制代码
# 将请求信息暂存, 放到最后一起打印
access_by_lua_block {
  ngx.req.read_body()
  local req_body = ngx.req.get_body_data()
  local req_uri = ngx.var.request_uri
  if req_body and #req_body > 1024 * 1024 then
    req_body = "Request too large"
  end
  if not req_body then
    req_body = "No request body"
  end
  local headers = ngx.req.get_headers()
  local header_str = ""
  for k, v in pairs(headers) do
    header_str = header_str .. string.format("%s: %s\n", k, v)
  end
  ngx.ctx.req_info = {
    uri = req_uri,
    body = req_body,
    headers = header_str
  }
}

body_filter_by_lua_block {
  local resp_body = ngx.arg[1]
  local req_info = ngx.ctx.req_info or {}
  local req_uri = req_info.uri or "Unknown URI"
  local req_body = req_info.body or "Unknown Request Body"
  local req_headers = req_info.headers or "Unknown Headers"
  local resp_headers = ngx.resp.get_headers()
  local resp_header_str = ""
  for k, v in pairs(resp_headers) do
    resp_header_str = resp_header_str .. string.format("%s: %s\n", k, v)
  end
  ngx.log(ngx.ERR, string.format(
      "Request URI: %s\nRequest Headers:\n%sRequest Body: %s\nResponse Headers:\n%sResponse Body: %s",
      req_uri,
      req_headers,
      req_body,
      resp_header_str,
      resp_body or "No response body"
    ))
}

这段逻辑在location中.

完整内容可参考: https://github.com/hujingnb/docker_composer/tree/master/openresty

简单记录一下, 以方便后续获取请求使用

相关推荐
市场部需要一个软件开发岗位3 分钟前
JAVA开发常见安全问题:Cookie 中明文存储用户名、密码
android·java·安全
忆~遂愿7 分钟前
GE 引擎进阶:依赖图的原子性管理与异构算子协作调度
java·开发语言·人工智能
MZ_ZXD00112 分钟前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
PP东14 分钟前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
ManThink Technology19 分钟前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
invicinble24 分钟前
springboot的核心实现机制原理
java·spring boot·后端
人道领域32 分钟前
SSM框架从入门到入土(AOP面向切面编程)
java·开发语言
大模型玩家七七1 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
CodeToGym1 小时前
【Java 办公自动化】Apache POI 入门:手把手教你实现 Excel 导入与导出
java·apache·excel
凡人叶枫2 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发