Go 1.25 http.CrossOriginProtection 怎么拦跨源不安全请求:请求头判断与路由接入
来源:17golang原创
时间:2026-08-27 22:50:32 395浏览 收藏
升级到 Go 1.25 后,如果一个带 Cookie 的写接口需要挡住跨站表单或脚本请求,可以把 http.CrossOriginProtection 放在现有路由前面。它依据浏览器的 Sec-Fetch-Site 和 Origin 判断跨源关系,安全方法继续通过,疑似跨源的非安全请求默认返回 403 Forbidden。
最小接入方式是用
http.NewCrossOriginProtection().Handler(mux)包住业务路由;先确认写操作没有放在 GET 上,再按实际前端来源补充可信 Origin。
- GET、HEAD、OPTIONS 属于安全方法,保护器不会替业务承担写操作约束。
- 带有
Sec-Fetch-Site或Origin的跨源非安全请求会进入Check判定。 - 把保护器放在
Handler外层后,拒绝请求不会进入业务处理函数。 - 无这两个请求头的请求会被当作同源或非浏览器请求,不能把它当成完整的身份认证。
跨源写请求为什么会在入口被挡住
现场通常很简单:页面正常打开,GET 查询也正常,但从另一个站点提交 POST 时得到 403。先别急着在业务函数里加一堆来源判断。浏览器会带上 Sec-Fetch-Site,也可能带上 Origin;保护器在进入应用路由前读取这些信号,并把安全方法和非安全方法分开处理。
这项能力不是 Cookie 校验,也不是 CSRF token。它的价值是给一组已经存在的 net/http 路由增加统一的跨源请求门槛。真正改变数据的接口仍然应该使用 POST、PUT、PATCH 或 DELETE,并在业务层继续验证身份、权限和输入。
先用 Check 看清请求头判定链
如果需要在中间件接入前观察拒绝原因,可以直接调用 Check。下面的示例只打印判定结果,不执行任何写操作;测试时用 httptest.NewRequest 逐个补齐请求头。
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func main() {
protection := http.NewCrossOriginProtection()
req := httptest.NewRequest(http.MethodPost, "http://api.example.test/orders", nil)
req.Header.Set("Sec-Fetch-Site", "cross-site")
req.Header.Set("Origin", "https://shop.example.test")
if err := protection.Check(req); err != nil {
fmt.Println(err)
return
}
fmt.Println("request allowed")
}
这段测试里,Sec-Fetch-Site 和 Origin 是输入,Check 是判定点。两个信号的具体组合交给标准库处理,不要在业务代码里复制一份不完整的规则。官方文档还明确说明:GET、HEAD、OPTIONS 总是允许,因此不能把“请求通过保护器”理解成“请求安全”。

把 Handler 放到 ServeMux 外层
生产接入点应当是统一的 HTTP 入口。业务路由继续负责返回成功结果,保护器负责在调用链前面拦截请求:
mux := http.NewServeMux()
mux.HandleFunc("/orders", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("request allowed"))
})
protection := http.NewCrossOriginProtection()
server := &http.Server{
Addr: ":8080",
Handler: protection.Handler(mux),
}
// http.ListenAndServe(server.Addr, server.Handler)
当请求被 Handler 判定为不允许时,业务函数不会被调用,默认响应是 403 Forbidden。允许的请求才会继续抵达 ServeMux,最后得到 request allowed。这条边界很重要:拒绝响应应在入口统一观察,订单写入、审计日志和幂等键处理都不应在拒绝之后才补救。

可信来源和旁路规则要谨慎添加
同一套 API 同时服务多个前端域名时,可以调用 AddTrustedOrigin 放行精确匹配的 Origin。它接受形如 scheme://host[:port] 的值,生产环境不要把整段来源匹配写成宽泛通配。
AddInsecureBypassPattern 的语义更强:匹配该路径的请求全部允许,而且规则使用 ServeMux 的模式和优先级。它适合经过明确评审的兼容入口,不适合用来给所有写接口开后门。若规则冲突或模式非法,方法会 panic;配置应在服务启动阶段完成。
| 场景 | 处理建议 |
|---|---|
| 同源后台提交 POST | 保持默认保护,验证登录态和权限 |
| 固定前端域名提交 POST | 添加精确的 AddTrustedOrigin |
| 兼容旧客户端的指定路径 | 单独评审旁路模式,并记录原因 |
| GET 修改订单状态 | 先改接口语义,不能靠保护器兜底 |
怎样验证拒绝、放行和回滚
上线前至少做三组请求:同源写请求、跨源写请求和安全方法请求。观察业务处理函数是否被调用、状态码是否符合预期,以及审计日志中是否能区分被入口拒绝的请求。
- 拒绝检查:POST 携带
Sec-Fetch-Site: cross-site,预期得到403 Forbidden,业务日志不应出现订单写入。 - 放行检查:使用已配置的精确 Origin,再发同一个 POST,预期进入业务函数并返回
request allowed或真实业务结果。 - 安全方法检查:GET、HEAD、OPTIONS 即使跨源也会通过保护器,必须确认它们没有改变状态。
如果兼容性问题集中在某个前端来源,优先回滚这次中间件接入,再单独核对 Origin 和部署域名;不要为了恢复流量直接增加全路径旁路。
相关问题
没有 Sec-Fetch-Site 和 Origin 的请求会怎样?
标准库目前把它们当作同源或非浏览器请求而允许。它不能替代登录认证、权限检查或请求签名。
CrossOriginProtection 能代替 CSRF token 吗?
它提供的是跨源请求保护,不是业务级 token 校验。高风险写操作仍可叠加 token、SameSite Cookie 和权限校验。
为什么 GET 跨源请求没有被拒绝?
GET、HEAD、OPTIONS 被定义为安全方法。若 GET 会修改订单、余额或配置,应改成语义正确的非安全方法。
收尾检查
接入 http.CrossOriginProtection 的关键不是把所有请求挡住,而是让跨源写请求在统一入口先经过可解释的判定。保留真实来源、方法语义和业务权限三层检查,出现误拦截时也能只回滚中间件配置,不动订单处理代码。
-
480 收藏
-
196 收藏
-
100 收藏
-
282 收藏
-
298 收藏
-
112 收藏
-
Golang · Go教程 | 1小时前 | 标准库 · 签名 · Go教程 · 密码学 · 接口兼容 · Go Go 1.25 crypto.MessageSigner SignMessage 签名器453 收藏
-
Golang · Go教程 | 1小时前 | goroutine · pprof · 性能分析 · Go教程 · 运行时 · Go label runtime/pprof Do ForLabels goroutine 归因447 收藏
-
Golang · Go教程 | 2小时前 | 网络编程 · IPv6 · Go教程 · 代码质量 · go vet · IPv6 net.Dial Go 1.25 go vet hostport net.JoinHostPort284 收藏
-
387 收藏
-
294 收藏
-
216 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习