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
| Header | Value | Deskripsi |
|---|---|---|
Access-Control-Allow-Origin | * | Mengizinkan semua origin |
Access-Control-Max-Age | 86400 | Cache preflight request selama 24 jam |
Access-Control-Allow-Methods | POST, GET, OPTIONS, PUT, DELETE, UPDATE | HTTP methods yang diizinkan |
Access-Control-Allow-Headers | Origin, Content-Type, ... | Request headers yang diizinkan |
Access-Control-Expose-Headers | Content-Length | Response headers yang dapat diakses |
Access-Control-Allow-Credentials | true | Mengizinkan cookies/credentials |
Cache-Control | no-cache | Disable 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
| Header | Deskripsi |
|---|---|
Origin | Origin of the request |
Content-Type | MIME type of request body |
api_key | API key for authentication |
Content-Length | Size of request body |
Accept-Encoding | Accepted encodings |
X-CSRF-Token | CSRF protection token |
Authorization | JWT 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")