CORS Middleware
The CORS (Cross-Origin Resource Sharing) middleware handles cross-origin resource sharing, allowing you to control which domains can access your API resources.
Usage
Basic Usage
import ( "go-slim.dev/slim" "go-slim.dev/slim/middleware")func main() { s := slim.New() // Use default configuration s.Use(middleware.CORS()) s.GET("/api/users", func(c slim.Context) error { return c.JSON(200, map[string]string{"message": "Hello"}) }) s.Start(":8080")}Custom Configuration
s := slim.New()s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"https://example.com", "https://app.example.com"}, AllowMethods: []string{"GET", "POST", "PUT", "DELETE"}, AllowHeaders: []string{"Content-Type", "Authorization"}, AllowCredentials: true, ExposeHeaders: []string{"X-Request-ID"}, MaxAge: 3600,}))Configuration Options
CORSConfig
type CORSConfig struct { // AllowOrigins defines a list of origins that may access the resource // Optional. Default value []string{"*"} AllowOrigins []string // AllowOriginFunc is a custom function to validate the origin // If this option is set, AllowOrigins is ignored // Optional AllowOriginFunc func(origin string) (bool, error) // AllowMethods defines a list methods allowed when accessing the resource // Used in response to a preflight request // Optional. Default value includes common methods AllowMethods []string // AllowHeaders defines a list of request headers that can be used // Used in response to a preflight request // Optional. Default value []string{} AllowHeaders []string // AllowCredentials indicates whether the response can be exposed // when the credentials flag is true // Optional. Default value false AllowCredentials bool // ExposeHeaders defines the whitelist headers that clients are allowed to access // Optional. Default value []string{} ExposeHeaders []string // MaxAge indicates how long (in seconds) the results of a preflight // request can be cached // Optional. Default value 0 MaxAge int}Examples
1. Allow All Origins (Development)
s.Use(middleware.CORS())The default configuration allows all origins (AllowOrigins: []string{"*"}), suitable for development environments.
2. Restrict Specific Domains
s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{ "https://example.com", "https://app.example.com", },}))3. Use Wildcard Patterns
s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{ "https://*.example.com", // Allow all subdomains of example.com "http://localhost:*", // Allow localhost on all ports },}))4. Custom Origin Validation Function
s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOriginFunc: func(origin string) (bool, error) { // Custom logic, e.g., query from database allowedOrigins := []string{ "https://example.com", "https://app.example.com", } for _, allowed := range allowedOrigins { if origin == allowed { return true, nil } } return false, nil },}))5. Support Credentials (Cookies)
s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{"https://example.com"}, AllowCredentials: true, AllowHeaders: []string{"Content-Type", "Authorization"},}))Note: When AllowCredentials: true, AllowOrigins cannot be set to ["*"]. You must specify concrete domain names.
6. Complete Configuration Example
s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{ "https://example.com", "https://app.example.com", }, AllowMethods: []string{ "GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", }, AllowHeaders: []string{ "Origin", "Content-Type", "Accept", "Authorization", "X-Request-ID", }, ExposeHeaders: []string{ "X-Request-ID", "X-Response-Time", }, AllowCredentials: true, MaxAge: 3600, // 1 hour}))How It Works
Simple Requests
For simple requests, the CORS middleware:
- Checks the
Originheader - Validates if the origin is in the allow list
- If allowed, sets the
Access-Control-Allow-Originresponse header - If
AllowCredentialsis configured, sets the corresponding response header - Continues processing the request
Preflight Requests
For preflight requests (HTTP OPTIONS), the CORS middleware:
- Checks the
Originheader - Validates if the origin is in the allow list
- Sets
Access-Control-Allow-Origin - Sets
Access-Control-Allow-Methods - Sets
Access-Control-Allow-Headers - If
MaxAgeis configured, setsAccess-Control-Max-Age - Returns
204 No Contentstatus code
Default Configuration
CORSConfig{ AllowOrigins: []string{"*"}, AllowMethods: []string{ "GET", "HEAD", "PUT", "PATCH", "POST", "DELETE", }, AllowHeaders: []string{}, AllowCredentials: false, ExposeHeaders: []string{}, MaxAge: 0,}Best Practices
1. Restrict Origins in Production
// Development environmentif os.Getenv("ENV") == "development" { s.Use(middleware.CORS())} else { // Production environment s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: []string{ "https://yourdomain.com", "https://app.yourdomain.com", }, AllowCredentials: true, }))}2. Use Environment Variables
allowedOrigins := strings.Split(os.Getenv("ALLOWED_ORIGINS"), ",")s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowOrigins: allowedOrigins,}))3. Limit Exposed Headers
Only expose headers that clients actually need:
s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ ExposeHeaders: []string{ "X-Request-ID", "X-Total-Count", // May be needed for pagination },}))4. Set Reasonable MaxAge
Setting a reasonable cache time can reduce the number of preflight requests:
s.Use(middleware.CORSWithConfig(middleware.CORSConfig{ MaxAge: 86400, // 24 hours}))Security Considerations
-
Never use
AllowOrigins: ["*"]in production - this allows any website to access your API -
Use
AllowCredentials: truewith caution - ensure you understand the security implications -
Limit
AllowMethods- only allow necessary HTTP methods -
Limit
AllowHeaders- only allow necessary request headers -
Use HTTPS - avoid transmitting sensitive information over insecure connections
Common Questions
Q: Why is my CORS request failing?
A: Check the following:
- Is the CORS middleware properly configured on the server?
- Does
AllowOriginsinclude the client’s domain? - If using credentials (Cookies), is
AllowCredentials: trueset? - Are
AllowHeadersandAllowMethodscorrectly configured?
Q: What is a preflight request?
A: A preflight request is an OPTIONS request automatically sent by the browser before certain cross-origin requests to check if the server allows the actual request.
Q: Can AllowOrigins: ["*"] and AllowCredentials: true be used together?
A: No. For security reasons, when credentials are enabled, you must specify concrete origins, not the wildcard *.