cors

Configurable CORS middleware for the Gin web framework in Go, with fine-grained origin, header, and credential rules.

Library
Go
vv1.7.8
2,003stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
69/100Good
Development Activity72
Maintenance48
Community56
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture78
Code Quality88
Innovation85
Learning Curve65

gin-contrib/cors is the official Cross-Origin Resource Sharing (CORS) middleware for the Gin HTTP framework. It plugs into a Gin router as a single Use() call and handles preflight OPTIONS requests and response headers for cross-origin browser requests, so application code never has to hand-roll Access-Control-* header logic.

Configuration is driven by a single Config struct covering allowed origins (exact, wildcard, or a custom validator function), allowed methods and headers, credentialed requests, exposed headers, preflight cache duration (MaxAge), private network access, and non-HTTP origin schemes such as browser extensions, WebSockets, and file://. A Validate() step catches conflicting settings (e.g. allowing all origins while also requiring credentials) before the middleware is even constructed, turning a class of runtime CORS bugs into an explicit startup error.

For teams running a Gin API that’s consumed from a separate frontend origin, it replaces bespoke header-setting middleware with a well-tested, actively maintained package that already handles the edge cases (wildcard subdomains, custom schemes, per-request origin callbacks) that are easy to get subtly wrong when implemented by hand.

What You Get

  • One-line integration via cors.Default() (allow-all) or cors.New(config) for custom rules, added with a single router.Use() call
  • A Config struct covering allowed origins, methods, headers, exposed headers, credentials, and preflight cache duration (MaxAge)
  • Wildcard origin matching (https://*.example.com) and support for non-HTTP schemes: browser extensions, WebSockets (ws:///wss://), and file://
  • Custom origin validation via AllowOriginFunc or the context-aware AllowOriginWithContextFunc for per-request logic (e.g. header-gated origins)
  • Fluent helper methods (AddAllowMethods, AddAllowHeaders, AddExposeHeaders) to extend a base config incrementally
  • Built-in Validate() that rejects conflicting configuration (e.g. AllowAllOrigins combined with credentials) at construction time instead of failing silently at request time

Common Use Cases

  • Allowing a separately hosted single-page app (React/Vue/etc.) to call a Gin-based JSON API from a different origin
  • Locking down a production API to an explicit list of trusted origins while allowing credentialed (cookie/auth-header) requests
  • Supporting wildcard subdomains for multi-tenant SaaS apps where each tenant gets its own subdomain origin
  • Enabling CORS for desktop or extension clients that call the API from non-HTTP origins like tauri:// or chrome-extension://
  • Tuning preflight caching (MaxAge) to reduce redundant OPTIONS round-trips for high-traffic browser clients

Under The Hood

Architecture The package splits cleanly into three files by responsibility: cors.go exposes the public surface — the Config struct, its Validate()/parseWildcardRules() methods, and the Default()/New() constructors that return a gin.HandlerFunc; config.go holds the internal cors struct that does the actual per-request work (applyCors, validateOrigin, validateWildcardOrigin), constructed once via newCors() from a validated Config; and utils.go contains pure header-generation and string-normalization helpers. A deliberate performance choice runs through the design: normal-request and preflight-request header sets (normalHeaders, preflightHeaders) are computed once at middleware-construction time rather than rebuilt on every request, so the hot path in applyCors only does origin comparison and a header-map copy.

Tech Stack A small, dependency-light Go module (go 1.25) whose only non-test runtime dependency is github.com/gin-gonic/gin (the framework it extends); stretchr/testify is used for test assertions. Releases are cut with GoReleaser (.goreleaser.yaml), CI runs on GitHub Actions (go.yml), and the repo layers in CodeQL static analysis and a Trivy vulnerability scan as separate workflows alongside Dependabot for automated dependency bumps.

Code Quality Testing is extensive relative to the package’s size — cors_test.go alone covers single- and multi-route-group routers, mixed-case HTTP methods, every origin-matching mode (exact, wildcard, regex-style, browser-extension schemes), credentialed vs. non-credentialed flows, and preflight-specific headers, all via table-driven-style helpers (performRequestWithHeaders) and testify/assert. A .golangci.yml pins the linter configuration, and the CodeQL/Trivy workflows add static and dependency-vulnerability scanning on top of the standard test suite. No test files were found to be missing coverage for any exported behavior observed during review.

API Design The public API favors progressive disclosure: cors.Default() needs zero configuration for a permissive dev setup, cors.DefaultConfig() gives sane starting defaults to customize, and cors.New(cors.Config{...}) exposes every knob for production use. Every exported field on Config carries a doc comment explaining its default and effect, and the README pairs a full configuration-reference table with runnable snippets for the most common patterns (custom origin functions, context-aware validation, wildcard subdomains). Misconfiguration fails fast and explicitly via Validate() rather than producing silently-wrong CORS headers, which is a meaningfully better failure mode than most hand-rolled middleware of this kind.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search