jub0bs/cors

GitHub: jub0bs/cors

一个为 Go 语言设计的 CORS 中间件库,以安全默认配置和高性能为特色,帮助开发者正确实现跨域资源共享。

Stars: 180 | Forks: 5

# jub0bs/cors [![tag](https://img.shields.io/github/tag/jub0bs/cors.svg)](https://github.com/jub0bs/cors/tags) [![Go 版本](https://img.shields.io/badge/Go-%3E%3D%201.25-%23007d9c)][go1.25] [![Go 参考](https://pkg.go.dev/badge/github.com/jub0bs/cors.svg)](https://pkg.go.dev/github.com/jub0bs/cors) [![license](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat)](https://github.com/jub0bs/cors/raw/main/LICENSE) [![build](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/2519d28ac7121019.svg)](https://github.com/jub0bs/cors/actions/workflows/cors.yml) [![codecov](https://codecov.io/gh/jub0bs/cors/branch/main/graph/badge.svg?token=N208BHWQTM)](https://app.codecov.io/gh/jub0bs/cors/tree/main) [![goreport](https://goreportcard.com/badge/jub0bs/cors)](https://goreportcard.com/report/jub0bs/cors) 一个固执己见的 [Go][golang] [CORS][mdn-cors] 中间件库, 旨在比现有替代方案 更易于使用且更难被误用。 ## 关于 CORS [同源策略 (SOP)][mdn-sop] 是一种安全机制, Web 浏览器实施该机制以保护其用户。 具体而言,SOP 在发送和读取两方面 对跨源网络访问施加了某些限制。 [跨源资源共享 (CORS)][mdn-cors] 是一种协议, 允许服务器指示浏览器为特定客户端放宽这些限制。 ## 功能 该库允许你配置和构建实现 CORS 的 [net/http][net-http] 中间件。 它通过提供以下功能与其他 CORS 中间件库区分开来: - 完全符合 [Fetch 标准][fetch]; - [简单、连贯且声明式的 API][pkgsite-index]; - [详尽的文档][pkgsite]; - [广泛的配置验证][validation]; - [默认安全的中间件][safe]; - [强有力的性能保证][benchmark-results]; - [有用的调试模式][debug]; - [即时、并发安全的中间件可重配性][reconfigurable]; - [配置错误的程序化处理][reconfigurable] (有助于实现 [RFC 9457][rfc9457])。 ## 安装 ``` go get github.com/jub0bs/cors ``` 该库需要 [Go 1.25.0][go1.25] 或更高版本。 根据 [Go 发布策略][release-policy],它仅支持 Go 的两个最新主要版本,即 1.25 和 1.24。 ## 示例 以下程序演示了如何创建一个 CORS 中间件,该中间件 - 允许来自 [Web 源][web-origin] `https://example.com` 的匿名访问, - 请求方法为 `GET` 或 `POST`(或 `HEAD`),以及 - (可选)带有请求头 `Authorization`, 并演示了如何将上述中间件应用于 `/api/` 路径下可访问的所有资源: ``` package main import ( "io" "log" "net/http" "github.com/jub0bs/cors" ) func main() { mux := http.NewServeMux() mux.HandleFunc("GET /hello", handleHello) // note: not configured for CORS // create CORS middleware cors, err := cors.NewMiddleware(cors.Config{ Origins: []string{"https://example.com"}, Methods: []string{http.MethodGet, http.MethodPost}, RequestHeaders: []string{"Authorization"}, }) if err != nil { log.Fatal(err) } cors.SetDebug(true) // turn debug mode on (optional) api := http.NewServeMux() api.HandleFunc("GET /users", handleUsersGet) api.HandleFunc("POST /users", handleUsersPost) mux.Handle("/api/", http.StripPrefix("/api", cors.Wrap(api))) // note: method-less pattern here if err := http.ListenAndServe(":8080", mux); err != http.ErrServerClosed { log.Fatal(err) } } func handleHello(w http.ResponseWriter, _ *http.Request) { io.WriteString(w, "Hello, World!") } func handleUsersGet(_ http.ResponseWriter, _ *http.Request) { // omitted } func handleUsersPost(_ http.ResponseWriter, _ *http.Request) { // omitted } ``` 将此程序保存到名为 `server.go` 的文件中,自己尝试一下。 如果你的机器上的端口 8080 恰好不可用,你可能需要调整端口号。 然后构建并运行你的服务器: ``` go build server.go ./server ``` 如果没有发生错误,服务器现在正在 `localhost:8080` 上运行, 并且 `/api/` 路径下可访问的各种资源现已按需配置了 CORS。 如果你需要以编程方式处理 CORS 配置错误, 请参阅 [package cfgerrors][cfgerrors]。 ## 文档 文档可在 [pkg.go.dev][pkgsite] 上获取。 ## 代码覆盖率 ![coverage](https://codecov.io/gh/jub0bs/cors/branch/main/graphs/sunburst.svg?token=N208BHWQTM) ## 许可证 所有源代码均受 [MIT 许可证][license] 保护。 ## 常见问题解答 ### 该库的性能优于 [rs/cors][rs-cors] 吗? 是的,至少根据[我的微基准测试的最新结果][cors-benchmarks]是这样。 ### 我可以结合第三方路由器使用该库吗? 答案取决于你打算使用哪个路由器; 有关指导,请参阅 [jub0bs/cors-examples][cors-examples]。 ### 如果我在指定允许的源时需要更大的灵活性怎么办? 出于安全考虑,该库仅支持受限的[源模式][origin-patterns]集合。 如果你需要更大的灵活性,请 fork 该库或依赖其他 CORS 中间件库, 例如 [rs/cors][rs-cors]。但请记住, [在这方面的过度灵活性意味着安全风险][danger]。 此外,如果你需要更新 CORS 中间件允许的源集合, 请注意你可以[即时重新配置它][middleware-reconfigure]。 ### 我可以基于某些 URL 查询参数选择性地应用 CORS 吗? 不可以。 ### 我可以将 CORS 中间件配置为为其处理的每个请求记录一条消息吗? 不可以,[这是有充分理由的][logging]。 如果你确实需要这样做,要么将你的 CORS 中间件包装在日志中间件中, 要么依赖不同的 CORS 中间件库,例如 [rs/cors][rs-cors]。 此外,如果你需要排查 CORS 预检失败, 你应该暂时[激活你的 CORS 中间件的调试模式][middleware-debug]。 ### 我可以指定一个自定义状态码来指示预检成功吗? [Fetch 标准][fetch] 规定, [200-299 范围内的任何状态码][ok-status] 都可以用于指示预检成功。 不幸的是,一些(极少数)不合规的客户端 如果对 CORS 预检请求的响应使用的状态码不是 200,则会导致 CORS 预检失败。 为了简单起见并符合 Fetch 标准,该库 始终使用状态码 204 来指示预检成功。 如果你需要指定自定义状态码来指示预检成功, 请 fork 该库或依赖其他 CORS 中间件库, 例如 [rs/cors][rs-cors]。 ### 我想编写检查 CORS 行为的测试。我该知道些什么? 你不需要编写此类测试,因为该库拥有广泛的测试套件。 但如果你坚持编写此类测试,请注意,出于性能原因, 该库生成的 CORS 中间件严格遵守(由 [Fetch 标准][fetch] 提供的) 关于某些 CORS 头部格式的保证。 特别是,如果你希望通过包含 [`Access-Control-Request-Headers` 头部][acrh] 的 CORS 预检请求来测试 CORS 中间件, 请记住,你应该按以下方式指定该头部值中以逗号分隔的元素: - 小写, - 按字典顺序排序, - 无重复。 否则,CORS 中间件将导致预检失败。 ### 如果我希望配置中介以便它们缓存对 CORS 预检请求的响应,我该怎么做? 请参阅 [包文档注释][pkg-comment] 中的倒数第二个要点。 ## 其他资源 - [_Fearless CORS: a design philosophy for CORS middleware libraries (and a Go implementation)_][fearless-cors] (博客文章) - [_jub0bs/cors: a better CORS middleware library for Go_][a-better-cors-lib] (博客文章) - [_Reconfigurable CORS middleware with jub0bs/cors_][reconfigurable] (博客文章) - [_Programmatic handling of CORS-configuration errors with jub0bs/cors_][programmatic] (博客文章) - [_Useful Functional-Options Tricks for Better Libraries_ (GopherCon Europe 2023)][funcopts] (视频) - [github.com/jub0bs/fcors][fcors] (该库的前身,现已归档)
标签:API安全, CISA项目, CORS, Go, Golang, JSON输出, MIT许可, net/http, Ruby工具, Syscall, Web安全, Web开发, 中间件, 中间件库, 同源策略, 后端开发, 安全编程, 并发安全, 开源库, 性能优化, 搜索引擎爬虫, 日志审计, 检测绕过, 网络安全, 蓝队分析, 跨域资源共享, 配置验证, 隐私保护