buffalo的cors中间件不生效,因其默认仅开发环境启用、注册顺序靠前易被覆盖,且websocket需upgrader手动校验origin,反向代理还可能丢弃响应头。

Buffalo 的 CORS 中间件不生效?检查是否被后续中间件覆盖
Buffalo 自带的 middleware.CORS 默认只在开发环境(env == "development")下启用,生产环境直接跳过。更关键的是,它注册顺序靠前,若你手动加了 app.Use(middleware.Logger) 或自定义 header 注入逻辑在它之后,就可能被覆盖或重写 Access-Control-Allow-Origin。确认实际生效的中间件链:在 app.go 里打印 app.Middleware 长度,或用 curl -I http://localhost:3000/any-path 看响应头是否含 CORS 字段。
用 middleware.CORS 配置白名单时,Origin 必须显式校验
别设 AllowOrigins: []string{"*"} —— 这在带凭证(credentials: true)的请求下会被浏览器拒绝。正确做法是:用函数动态比对 r.Header.Get("Origin"),且只放行可信域名:
middleware.CORS(&middleware.CORSOptions{
AllowOrigins: []string{},
AllowOriginFunc: func(origin string) bool {
for _, o := range []string{"https://myapp.com", "https://staging.myapp.com"} {
if origin == o {
return true
}
}
return false
},
AllowCredentials: true,
ExposeHeaders: []string{"X-Request-ID"},
})
漏掉 AllowOriginFunc 或返回 true 无条件放行,会暴露接口给任意站点,极易被 CSRF 或恶意脚本调用。
WebSocket 跨域不能靠 middleware.CORS,必须在 Upgrade 前校验
Buffalo 的 middleware.CORS 对 WebSocket 升级请求(Upgrade: websocket)完全无效,因为它是 HTTP 中间件,而 Upgrade 是连接级协商。你必须在 websocketHandler 里手动校验 Origin:
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
- 用
gorilla/websocket.Upgrader的CheckOrigin字段,不是AllowOrigins -
CheckOrigin函数接收 *http.Request,需自己取r.Header.Get("Origin")并比对 - 禁止写成
func(r *http.Request) bool { return true },否则 DDoS 扫描可瞬间耗尽连接数
示例片段:
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
origin := r.Header.Get("Origin")
return origin == "https://myapp.com" || origin == "https://staging.myapp.com"
},
}
反向代理(如 Nginx、Cloudflare)可能静默丢弃 CORS 头
即使 Buffalo 返回了正确的 Access-Control-Allow-Origin,Nginx 若未配置 add_header 透传,或 Cloudflare 的“Browser Integrity Check”开启,都可能导致 CORS 头丢失。验证方式:绕过代理直连 Buffalo 端口(如 :3000),若此时正常,则问题出在代理层。Nginx 关键配置:
location / {
proxy_pass http://buffalo_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,Authorization,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Accept-Encoding' always;
}
注意:always 参数确保对 204/304 等非 200 响应也注入头;Cloudflare 需关闭“Hotlink Protection”并检查 Page Rules 是否强制重写响应头。
Upgrader 初始化时拦截,反向代理又可能二次过滤。三者稍有错位,前端就报 “No 'Access-Control-Allow-Origin' header”,但错误信息从不告诉你具体哪一层掉了链子。










