Beego中应使用ctx.Input.Header.Get()读取请求头,它大小写不敏感、自动合并重复键,比直接访问ctx.Request.Header更稳妥;获取真实IP须用ctx.Input.IP()而非手动解析X-Forwarded-For。

Beego 中用 ctx.Input.Header 读取请求头
Beego 的 Controller 实例通过 ctx(即 this.Ctx)暴露了标准的 http.Request 封装,获取请求头最直接、最可靠的方式就是调用 ctx.Input.Header.Get()。它底层调用的是 http.Header.Get(),自动处理大小写不敏感匹配和重复键合并。
常见错误是试图用 ctx.Input.Param() 或 ctx.Input.Query() 去取 header,这两个方法分别对应 URL 路径参数和查询字符串,跟请求头完全无关。
-
ctx.Input.Header.Get("Authorization")→ 正确,返回 Bearer token 字符串(如"Bearer xxx") -
ctx.Input.Header.Get("Content-Type")→ 正确,返回"application/json"等值 -
ctx.Input.Header.Get("X-Forwarded-For")→ 正确,注意多个代理时可能有逗号分隔,需自行解析 - 不要写
ctx.Input.Header.Get("authorization")——虽然 Go 的http.Header不区分大小写,但写全大驼峰更符合惯例,也避免 IDE 提示歧义
Beego 2.x 中 ctx.Request.Header 也能用,但要注意时机
在 Beego 2.x(基于 Go 1.16+ 的新架构)中,ctx.Request 是原生 *http.Request 指针,所以你也可以直接用 ctx.Request.Header.Get()。效果和 ctx.Input.Header.Get() 完全一致,因为后者内部就是转发给前者。
但要注意:如果在 Prepare() 方法之前访问 ctx.Request,可能因中间件未就绪导致 header 为空(比如某些自定义认证中间件会改写 header)。稳妥起见,统一走 ctx.Input.Header 接口,它是 Beego 框架层明确保证可用的入口。
- 推荐始终使用
ctx.Input.Header.Get("X-Real-IP")而非ctx.Request.Header.Get("X-Real-IP") - 若需遍历全部 header,用
for key, values := range ctx.Input.Header—— 注意values是[]string,每个 key 对应所有同名 header 值 - Beego 1.x 不支持直接访问
ctx.Request,强行调用会 panic
获取客户端真实 IP 时,别只依赖 X-Forwarded-For
很多用户想通过请求头拿到用户真实 IP,习惯性只读 X-Forwarded-For,但这在反向代理(Nginx、CDN)链路中极易被伪造或错位。Beego 提供了更健壮的封装:ctx.Input.IP()。
ctx.Input.IP() 内部按优先级顺序检查:X-Forwarded-For → X-Real-IP → RemoteAddr,并做了基础校验(如 IPv4/IPv6 格式、私有地址过滤),比手动解析安全得多。
- 正确做法:
ip := this.Ctx.Input.IP(),返回字符串,如"203.0.113.42" - 错误做法:
this.Ctx.Input.Header.Get("X-Forwarded-For")直接当 IP 用 —— 攻击者可构造X-Forwarded-For: 1.2.3.4, 5.6.7.8,你取第一个就中招 - 如需严格限制只信某个代理(比如只信任 Nginx),可关掉
EnableXSRF并在 Nginx 配置中用set $real_ip_from "10.0.0.0/8";,再配合 Beego 的AppConfig.Set("httpport", "8080")等环境控制
自定义 Header 名含下划线时,Nginx 默认会丢弃
如果你定义了类似 X-My_App-Version 这种带下划线的 header,在 Nginx 作为反向代理时,默认会被静默过滤(因为 underscores_in_headers off)。此时 Beego 应用永远收不到这个 header,调试时会以为代码有问题,其实是基础设施拦截了。
解决办法只有两个:要么改 header 名为短横线风格(X-My-App-Version),要么在 Nginx 配置里显式开启:underscores_in_headers on;。Go 标准库和 Beego 都支持下划线,问题出在 Nginx 层。
- Beego 日志里查不到该 header → 先 curl 直连 Beego 进程(绕过 Nginx),确认是否真没传过来
- curl 测试命令:
curl -H "X-My_App-Version: 1.2.3" http://localhost:8080/api - Nginx 配置片段:
location / {<br> underscores_in_headers on;<br> proxy_pass http://backend;<br>}
ctx.Input.Header)和原生 Go 接口(ctx.Request.Header)的适用边界,以及理解 header 在整个请求链路(客户端 → CDN → Nginx → Beego)中可能被修改或过滤的位置。


















