Skip to main content

CORS Middleware

Dokumentasi Cross-Origin Resource Sharing (CORS) middleware.

Overview

CORSMiddleware menangani CORS headers untuk memungkinkan cross-origin requests dari browser.

Function Signature

func CORSMiddleware() gin.HandlerFunc

Implementation

func CORSMiddleware() gin.HandlerFunc {
return func(ctx *gin.Context) {
ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
ctx.Writer.Header().Set("Access-Control-Max-Age", "86400")
ctx.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, api_key, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
ctx.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length")
ctx.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
ctx.Writer.Header().Set("Cache-Control", "no-cache")

if ctx.Request.Method == "OPTIONS" {
log.Println("OPTIONS")
ctx.AbortWithStatus(200)
} else {
ctx.Next()
}
}
}

CORS Headers

HeaderValueDeskripsi
Access-Control-Allow-Origin*Mengizinkan semua origin
Access-Control-Max-Age86400Cache preflight request selama 24 jam
Access-Control-Allow-MethodsPOST, GET, OPTIONS, PUT, DELETE, UPDATEHTTP methods yang diizinkan
Access-Control-Allow-HeadersOrigin, Content-Type, ...Request headers yang diizinkan
Access-Control-Expose-HeadersContent-LengthResponse headers yang dapat diakses
Access-Control-Allow-CredentialstrueMengizinkan cookies/credentials
Cache-Controlno-cacheDisable caching

Preflight Request

Untuk request dengan custom headers atau methods selain GET/POST, browser akan mengirim preflight request dengan method OPTIONS.

┌─────────┐                              ┌─────────┐
│ Browser │ │ Server │
└────┬────┘ └────┬────┘
│ │
│ OPTIONS /api/v1/users │
│ Origin: http://localhost:3000 │
│ Access-Control-Request-Method: DELETE │
│───────────────────────────────────────▶│
│ │
│ 200 OK │
│ Access-Control-Allow-Origin: * │
│ Access-Control-Allow-Methods: DELETE │
│◀───────────────────────────────────────│
│ │
│ DELETE /api/v1/users/123 │
│ Origin: http://localhost:3000 │
│ Authorization: Bearer xxx... │
│───────────────────────────────────────▶│
│ │
│ 200 OK │
│ {deleted: true} │
│◀───────────────────────────────────────│
│ │

Usage

func main() {
router := gin.Default()

// Apply CORS middleware globally
router.Use(middleware.CORSMiddleware())

// ... routes
}

Production Considerations

Security Warning

Menggunakan Access-Control-Allow-Origin: * tidak direkomendasikan untuk production. Sebaiknya batasi ke domain yang diizinkan.

Secure Configuration

func SecureCORSMiddleware(allowedOrigins []string) gin.HandlerFunc {
return func(ctx *gin.Context) {
origin := ctx.Request.Header.Get("Origin")

// Check if origin is allowed
for _, allowed := range allowedOrigins {
if origin == allowed {
ctx.Writer.Header().Set("Access-Control-Allow-Origin", origin)
break
}
}

// ... rest of headers
}
}

// Usage
router.Use(middleware.SecureCORSMiddleware([]string{
"https://sisappra.jakarta.go.id",
"https://admin.sisappra.jakarta.go.id",
}))

Allowed Headers

HeaderDeskripsi
OriginOrigin of the request
Content-TypeMIME type of request body
api_keyAPI key for authentication
Content-LengthSize of request body
Accept-EncodingAccepted encodings
X-CSRF-TokenCSRF protection token
AuthorizationJWT Bearer token

Troubleshooting

Error: "CORS policy: No 'Access-Control-Allow-Origin'"

Pastikan CORS middleware di-apply sebelum route handler:

// ✅ Correct
router.Use(middleware.CORSMiddleware())
router.GET("/api/users", getUsers)

// ❌ Incorrect
router.GET("/api/users", getUsers)
router.Use(middleware.CORSMiddleware())

Error: "Request header field X is not allowed"

Tambahkan header ke Access-Control-Allow-Headers:

ctx.Writer.Header().Set("Access-Control-Allow-Headers", 
"Origin, Content-Type, api_key, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Custom-Header")