go 27 lines · 1 tab

CORS allowlist middleware (no wildcard surprises)

Leah Thompson Jan 2026
1 tab
package middleware

import (
  "net/http"
)

func CORS(allowed map[string]struct{}) func(http.Handler) http.Handler {
  return func(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
      origin := r.Header.Get("Origin")
      if origin != "" {
        if _, ok := allowed[origin]; ok {
          w.Header().Set("Access-Control-Allow-Origin", origin)
          w.Header().Set("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
          w.Header().Set("Access-Control-Allow-Headers", "Authorization,Content-Type,Idempotency-Key")
          w.Header().Set("Vary", "Origin")
        }
      }

      if r.Method == http.MethodOptions {
        w.WriteHeader(http.StatusNoContent)
        return
      }
      next.ServeHTTP(w, r)
    })
  }
}
1 file · go Explain with highlit

CORS is one of those features that becomes security-sensitive by accident. Instead of Access-Control-Allow-Origin: *, I keep a strict allowlist and echo back the exact origin only when it’s approved. I also handle OPTIONS preflight requests explicitly and set Vary: Origin so caches don’t mix responses across origins. The important detail is credentials: if you ever set Access-Control-Allow-Credentials: true, you must never use wildcard origins. This middleware keeps the logic in one place and makes it easy to audit. In production, I treat the allowlist as configuration and include both local dev origins and the real domains. With this in place, frontend integration becomes predictable and you avoid accidental cross-site exposure.


Related snips

Share this code

Here's the card — post it anywhere.

CORS allowlist middleware (no wildcard surprises) — share card
Link copied