当前位置:首页 > 文章列表 > Golang > Go教程 > Go http.CrossOriginProtection 怎样给写接口加跨源请求保护

Go http.CrossOriginProtection 怎样给写接口加跨源请求保护

来源:17golang原创 2026-10-21 22:20:26 0浏览 收藏

如果一个 Go 服务有修改配置、提交表单或删除资源的写接口,想先挡住浏览器发起的非安全跨源请求,可以在 net/http 的 Handler 层接入 http.CrossOriginProtection。它会根据 Sec-Fetch-Site,以及 Origin 与 Host 的关系判断请求是否跨源;被判定为不允许的请求会在进入业务处理器前得到拒绝。

本文使用的官方地址:https://pkg.go.dev/net/http#CrossOriginProtection

这是一层跨源请求保护,不是登录系统,也不是授权系统。读者真正要做的是三件事:明确哪些写接口需要保护,给确实存在的前端来源配置可信 Origin,再把拒绝响应做成统一且不泄露内部细节的 403。

先区分保护范围

CrossOriginProtection 的核心价值是把“浏览器跨源请求是否可以触达 Handler”变成一个标准库层面的判断。它不需要你在每个 POST 处理函数里重复读取请求头,也不应该被误解成所有 HTTP 请求的身份验证器。

请求或配置处理方式工程含义
GET、HEAD、OPTIONS安全方法,保护器始终允许不要让安全方法承担修改状态的副作用
带跨源信号的 POST、PUT、PATCH、DELETE进入跨源检查不符合规则时在业务 Handler 前拒绝
没有 Sec-Fetch-Site 或 Origin 的请求当前实现通常按同源或非浏览器请求处理不能把它当作“已完成身份认证”
明确加入的可信 Origin允许该 Origin 的请求继续通过必须写完整的 scheme、host 和可选端口
CrossOriginProtection 根据 Sec-Fetch-Site、Origin 和 Host 判断安全方法与非安全写请求的跨源保护边界结构图
图1:跨源保护边界说明图,展示请求元数据、策略判断和业务 Handler 的关系。

这个边界很重要:安全方法“允许通过”并不意味着可以在 GET 中修改数据库;没有来源头的请求“允许继续”也不意味着它已经通过了用户登录和权限检查。跨源保护解决的是浏览器携带站点身份信息发起写操作时的一类请求入口问题。

把保护器接到 ServeMux

最小接入方式是创建保护器,用它的 Handler 包住已有的 ServeMux。保护器位于路由处理器之外,写接口仍然由原来的业务函数负责。

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("POST /settings", updateSettings)

    // 保护器统一包住路由,避免每个写接口各写一套来源判断。
    protection := http.NewCrossOriginProtection()
    handler := protection.Handler(mux)

    // 监听入口只接收包装后的 Handler,业务路由保持原样。
    log.Fatal(http.ListenAndServe(":8080", handler))
}

func updateSettings(w http.ResponseWriter, r *http.Request) {
    // 这里仍然要做登录、授权、参数校验和幂等控制。
    w.WriteHeader(http.StatusNoContent)
}

var _ = json.NewEncoder

示例中的保护器只负责跨源入口,updateSettings 仍要验证当前用户是否登录、是否有修改配置的权限,以及请求数据是否符合业务规则。把这些职责混到 CrossOriginProtection 中,会让后续排查变得困难。

配置可信 Origin

如果管理前端和 Go 服务不是同一个 Origin,可以调用 AddTrustedOrigin。参数是完整的 Origin,例如 https://admin.example.test,不是只写域名,也不是把路径拼进去。该方法返回错误,因此启动阶段应直接处理配置错误。

func buildHandler(mux http.Handler) (http.Handler, error) {
    protection := http.NewCrossOriginProtection()

    // Origin 要包含协议、主机和需要时使用的端口,避免模糊匹配。
    if err := protection.AddTrustedOrigin("https://admin.example.test"); err != nil {
        return nil, fmt.Errorf("添加可信 origin 失败: %w", err)
    }

    // 保护器放在路由外层,统一检查跨源浏览器请求。
    return protection.Handler(mux), nil
}

上面的片段需要在完整文件中引入 fmt。这里故意让配置错误向启动阶段返回,而不是忽略错误继续提供一个来源规则不完整的服务。开发、测试和生产环境的前端 Origin 也应分别配置,不要为了省事把任意来源加入信任列表。

用 SetDenyHandler 统一返回 403

默认拒绝结果是 403。如果 API 有统一的 JSON 错误格式,可以用 SetDenyHandler 替换默认处理器。拒绝处理器不要输出请求头原文、内部路由或调试堆栈,只返回足够让前端识别的稳定字段。

func configureDenyResponse(protection *http.CrossOriginProtection) {
    protection.SetDenyHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 拒绝原因只返回稳定错误码,不回显 Origin 等请求细节。
        w.Header().Set("Content-Type", "application/json; charset=utf-8")
        w.WriteHeader(http.StatusForbidden)
        _ = json.NewEncoder(w).Encode(map[string]string{
            "code":    "cross_origin_request_denied",
            "message": "跨源请求被拒绝",
        })
    }))
}

SetDenyHandler 只影响 Handler 发现应该拒绝的请求;直接调用 Check 时不会调用这个拒绝处理器。如果你在中间件链中手动调用 Check,就需要自己把错误转换成响应。

NewCrossOriginProtection、AddTrustedOrigin、SetDenyHandler 与 POST settings 业务处理器之间的静态关系结构图
图2:保护器接入结构图,展示可信 Origin、拒绝处理器和写接口 Handler 的关系。

几个容易混淆的边界

跨源保护不等于登录和授权

保护器只回答“这个请求是否符合跨源入口规则”。它不会验证 Session、JWT、API Key,也不会判断用户能否修改某一条配置。通过保护器之后,仍要执行认证、授权、输入校验和业务审计。

它不负责开放跨域读取

CORS 主要描述浏览器能否读取跨源响应,CrossOriginProtection 主要拒绝不安全的跨源浏览器请求。二者解决的问题不同;如果前端确实需要跨源读取响应,还应单独设计 CORS 响应头和允许范围。

不要把绕过模式当成默认配置

AddInsecureBypassPattern 的语义是让匹配路径绕过保护,名称本身已经说明了风险。只有在你能明确证明该路径不会改变状态、并且已经有其他入口控制时才考虑使用;不要用它来“修复”一个不清楚来源的 403。

上线前的判断清单

  • 写接口是否真的使用了 POST、PUT、PATCH 或 DELETE,且没有把修改动作藏在 GET 中?
  • 可信 Origin 是否包含正确的协议、主机和端口,并按环境分别配置?
  • 保护器是否包住了所有需要保护的路由,而不是只包住某一个 Handler?
  • 拒绝响应是否固定为 403 和稳定错误码,没有回显 Origin、Cookie 或内部堆栈?
  • 认证、授权、参数校验、幂等和审计是否仍然保留?
  • 是否把 CORS 需求和跨源写请求保护拆开设计?

如果你的目标是给 Go 的配置写接口加一层标准化的跨源请求保护,推荐把 CrossOriginProtection 放在路由外层,再用 AddTrustedOrigin 描述真实前端来源,用 SetDenyHandler 统一错误格式。它的适用力在于收紧请求入口,而不是替代整套 Web 安全控制。

相关问题

为什么 POST 请求没有 Origin 也可能继续执行?

官方实现会把缺少 Sec-Fetch-Site 或 Origin 的请求暂时视为同源或非浏览器请求。它不是通用的请求身份判断器,服务端仍要做好认证和授权。

可信 Origin 可以只写域名吗?

不建议。AddTrustedOrigin 接收的是完整 Origin,通常应写成包含协议、主机和端口的形式,避免把不同协议或端口混为一谈。

用了 CrossOriginProtection 还需要 CORS 吗?

如果前端需要读取跨源响应,仍可能需要 CORS;跨源保护和 CORS 的职责不同,不能用其中一个代替另一个。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go x509.CreateCertificate 怎样生成带 SAN 的本地测试证书Go x509.CreateCertificate 怎样生成带 SAN 的本地测试证书
上一篇
Go x509.CreateCertificate 怎样生成带 SAN 的本地测试证书
Go reflect.Value.SetZero 怎样清空可变值
下一篇
Go reflect.Value.SetZero 怎样清空可变值
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    582次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    620次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    652次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    617次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    433次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码