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

traefik网关鉴权中间件转发multipart/form-data请求的multipart: NextPart: EOF问题

1 问题

我有一个上传文件接口,实际请求是:

curl --location --request POST 'https://api.test.cn/file/upload' \
--header 'Authorization: 123' \
--header 'Connection: keep-alive' \
--header 'Content-Type: multipart/form-data; boundary=--------------------------045547357906535257406124' \
--form 'file=@"/tmp/1.txt"'

报错:

multipart: NextPart: EOF

2 原因分析

发现直接请求 pod 是可以的:

curl --location --request POST 'http://10.119.2.154:8080/file/upload' \
--header 'Authorization: 123' \
--header 'Connection: keep-alive' \
--header 'Content-Type: multipart/form-data; boundary=--------------------------045547357906535257406124' \
--form 'file=@"/tmp/1.txt"'

问题可能出现在网关层,我使用的是 Traefik 网关,查看 Traefik 日志有如下报错:

2025-08-04T02:58:38Z DBG github.com/traefik/traefik/v3/pkg/middlewares/auth/forward.go:180 > Remote error http://auth-service:10090/user/auth. StatusCode: 400 middlewareName=user-auth@kubernetescrd middlewareType=ForwardAuth 10.119.0.192 - - 
[04/Aug/2025:02:58:38 +0000] "POST /file/upload HTTP/1.1" 400 25 "-" "-" 3 "auth-api-route-ca8f0cd5d19177e62b04@kubernetescrd" "-" 2ms

user-auth 是一个 forwardAuth 中间件,用于做全局的用户鉴权,返回了400

Traefik forwardAuth 中间件配置为:

  forwardAuth:address: http://auth-service:10090/user/authauthResponseHeadersRegex: ^X-TesttrustForwardHeader: true

Traefik  未显式定义 authRequestHeaders,那它会将原始请求的所有头信息和完整 Body 都转发给认证服务,实际转发内容为:

  • 所有 Headers(包括 Content-Type: multipart/form-data)
  • 完整的文件二进制数据(通过 Body 传输)

而鉴权接口(/user/auth)只是为了校验 token,其入参解析逻辑为(使用go-zero框架):

// 认证接口入参解析
if err := httpx.Parse(r, &req); err != nil {httpx.ErrorCtx(r.Context(), w, err)return
}// go-zero源码 rest/httpx/requests.go
func Parse(r *http.Request, v any) error {kind := mapping.Deref(reflect.TypeOf(v)).Kind()if kind != reflect.Array && kind != reflect.Slice {if err := ParsePath(r, v); err != nil {return err}if err := ParseForm(r, v); err != nil {return err}if err := ParseHeaders(r, v); err != nil {return err}}if err := ParseJsonBody(r, v); err != nil {return err}if valid, ok := v.(validation.Validator); ok {return valid.Validate()} else if val := getValidator(); val != nil {return val.Validate(r, v)}return nil
}

也就是说,解析器解析到 Content-Type 是 multipart/form-data 格式,会尝试去解析这个包含文件二进制数据的 Body,但是鉴权接口并没有定义文件字段,解析器因格式不匹报了错:multipart: NextPart: EOF

3 解决

第一种:在 forwardAuth 中间件中显式定义转发的请求头

定义 authRequestHeaders,指定好需要转发哪些 Header,不要转发 Content-Type 

forwardAuth:address: http://auth-service:10090/user/authauthRequestHeaders:- Authorization- X-TestauthResponseHeadersRegex: ^X-TesttrustForwardHeader: true

此时认证服务收到的请求 Header 只有 Authorization 和 X-Test,而 Body 为空。

第二种:修改认证接口逻辑

由于认证接口可以忽略 Body,只需解析 Header,直接将 Parse() 改为 ParseHeaders()

// 认证接口入参解析
if err := httpx.ParseHeaders(r, &req); err != nil {httpx.ErrorCtx(r.Context(), w, err)return
}

虽然网关还是会把 Body 和 Header 全部转发过来,但是接口不做 Body 处理,就不会出现 Body 读取的问题了,而且无需为无用的 Body 分配内存。

http://www.lryc.cn/news/610347.html

相关文章:

  • LLM大模型时代:生活服务领域的“生存革命“与新生态重构
  • 深度学习-卷积神经网络CNN-卷积层
  • 探索机器学习在医疗领域的应用与挑战
  • Flask 项目 Windows 服务器部署全流程
  • C++信息学奥赛一本通-第一部分-基础一-第一章
  • RTX5060显卡安装cuda版本PyTorch踩坑记录
  • 深度解析:CPU 与 GPU 上的张量运算,为何“快”与“慢”并非绝对?
  • chatgpt plus简单得,不需要求人,不需要野卡,不需要合租,不需要昂贵的价格
  • 从 0 到 1 开发图书管理系统:飞算 JavaAI 让技术落地更简单
  • Oracle MCP Server简单配置以及备份调用
  • Oracle EBS ERP接口开发 — 修复bug基本流程
  • Calcite自定义扩展SQL案例详细流程篇
  • Centos Docker 安装手册(可用)
  • el-table高度自适应vue页面指令
  • Mac中M系列芯片采用rbenv管理ruby版本
  • 板子指示灯状态设计
  • 2SA2016-TD-E ON安森美 功率晶体管 0.18Ω超低压降+30MHz高频 工业电源专用
  • C语言的指针
  • python采集拍立淘按图搜索API接口,json数据参考
  • 2.4.3-2.4.8控制成本-控制资源-监督沟通-监督干系人-监督风险-控制采购
  • 每日任务day0804:小小勇者成长记之药剂师的小咪
  • 断点续传Demo实现
  • 【目标检测基础】——yolo学习
  • 设备电机状态监测中的故障诊断与定位策略
  • HCIP笔记1
  • 微信小程序本地存储与Cookie的区别
  • 【node】如何开发一个生成token的接口
  • DolphinScheduler 集成DataX
  • 【REACT18.x】封装react-rouer实现多级路由嵌套,封装登录态权限拦截
  • 《Python 实用项目与工具制作指南》· 2.1 输入输出