jub0bs/cors
GitHub: jub0bs/cors
一个为 Go 语言设计的 CORS 中间件库,以安全默认配置和高性能为特色,帮助开发者正确实现跨域资源共享。
Stars: 180 | Forks: 5
# jub0bs/cors
[](https://github.com/jub0bs/cors/tags)
[][go1.25]
[](https://pkg.go.dev/github.com/jub0bs/cors)
[](https://github.com/jub0bs/cors/raw/main/LICENSE)
[](https://github.com/jub0bs/cors/actions/workflows/cors.yml)
[](https://app.codecov.io/gh/jub0bs/cors/tree/main)
[](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] 上获取。
## 代码覆盖率

## 许可证
所有源代码均受 [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开发, 中间件, 中间件库, 同源策略, 后端开发, 安全编程, 并发安全, 开源库, 性能优化, 搜索引擎爬虫, 日志审计, 检测绕过, 网络安全, 蓝队分析, 跨域资源共享, 配置验证, 隐私保护