Slim

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:

  1. Checks the Origin header
  2. Validates if the origin is in the allow list
  3. If allowed, sets the Access-Control-Allow-Origin response header
  4. If AllowCredentials is configured, sets the corresponding response header
  5. Continues processing the request

Preflight Requests

For preflight requests (HTTP OPTIONS), the CORS middleware:

  1. Checks the Origin header
  2. Validates if the origin is in the allow list
  3. Sets Access-Control-Allow-Origin
  4. Sets Access-Control-Allow-Methods
  5. Sets Access-Control-Allow-Headers
  6. If MaxAge is configured, sets Access-Control-Max-Age
  7. Returns 204 No Content status 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

  1. Never use AllowOrigins: ["*"] in production - this allows any website to access your API

  2. Use AllowCredentials: true with caution - ensure you understand the security implications

  3. Limit AllowMethods - only allow necessary HTTP methods

  4. Limit AllowHeaders - only allow necessary request headers

  5. 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 AllowOrigins include the client’s domain?
  • If using credentials (Cookies), is AllowCredentials: true set?
  • Are AllowHeaders and AllowMethods correctly 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 *.

References

Navigate Select esc Close search