8.4 KiB
8.4 KiB
CORS 403 Hatası Çözümü
❌ Problem
OPTIONS https://goauth.beyhano.net.tr/v1/auth/login
Status: 403 Forbidden
Origin: https://nextgo.beyhano.net.tr
Hata Detayları:
- Frontend Origin:
https://nextgo.beyhano.net.tr - Backend:
https://goauth.beyhano.net.tr - HTTP Method: OPTIONS (preflight request)
- Status: 403 Forbidden
- Sorun: CORS middleware sadece
localhost:3000'e izin veriyor
✅ Çözüm
1. Dynamic CORS Middleware Aktif Edildi
Önce (main.go):
// Hardcoded CORS - sadece localhost
r.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:3000"},
...
}))
Sonra (main.go):
// Dynamic CORS - Database'den okuyor
settingsService := services.NewSettingsService()
r.Use(middlewares.DynamicCorsMiddleware(settingsService))
2. Whitelist'e Origin Ekleme
Production origin'ini whitelist'e ekleyin:
# Admin login
TOKEN=$(curl -s -X POST https://goauth.beyhano.net.tr/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@gauth.local","password":"Admin@123"}' | jq -r '.access_token')
# Frontend origin'ini whitelist'e ekle
curl -X POST https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"origin": "https://nextgo.beyhano.net.tr",
"description": "Production Next.js frontend"
}'
Başarılı Yanıt:
{
"id": "uuid",
"origin": "https://nextgo.beyhano.net.tr",
"description": "Production Next.js frontend",
"is_active": true,
"created_by": "admin@gauth.local",
"created_at": "2026-02-05T...",
"updated_at": "2026-02-05T..."
}
🔧 Dynamic CORS Middleware Nasıl Çalışır?
Akış:
- Request gelir →
Originheader kontrol edilir - Database kontrolü → Whitelist/Blacklist'ten origin aranır
- Cache kontrolü → Redis'te var mı? (1 saat TTL)
- Karar:
- ✅ Whitelist'te var → İzin ver
- ❌ Blacklist'te var → Reddet (403)
- ❌ Hiçbirinde yok → Reddet (403)
Code (dynamic_cors_middleware.go):
func DynamicCorsMiddleware(settingsService *services.SettingsService) gin.HandlerFunc {
return func(c *gin.Context) {
origin := c.Request.Header.Get("Origin")
// Check if origin is allowed
allowed, err := settingsService.IsOriginAllowed(origin)
if !allowed {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
"error": "Origin not allowed by CORS policy",
})
return
}
// Set CORS headers
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization")
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
c.Writer.Header().Set("Access-Control-Max-Age", "86400") // 24 hours
// Handle preflight requests
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
}
🚀 Production Deploy Sonrası Yapılacaklar
1. Container'a Bağlan
Dokploy dashboard veya SSH ile:
docker exec -it app_auth_central sh
2. Admin Kullanıcı Oluştur
./main seed-admin
Credentials:
- Email:
admin@gauth.local - Password:
Admin@123
3. Admin Login (Local veya cURL)
TOKEN=$(curl -s -X POST https://goauth.beyhano.net.tr/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@gauth.local","password":"Admin@123"}' | jq -r '.access_token')
echo "Token: ${TOKEN:0:30}..."
4. Frontend Origin'lerini Ekle
Development:
curl -X POST https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"origin": "http://localhost:3000",
"description": "Local development"
}'
Production (Next.js):
curl -X POST https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"origin": "https://nextgo.beyhano.net.tr",
"description": "Production Next.js frontend"
}'
Staging (opsiyonel):
curl -X POST https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"origin": "https://staging.beyhano.net.tr",
"description": "Staging environment"
}'
5. Doğrulama
# Whitelist'i kontrol et
curl -X GET https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" | jq '.[] | {origin, is_active}'
Beklenen Yanıt:
[
{
"origin": "https://nextgo.beyhano.net.tr",
"is_active": true
},
{
"origin": "http://localhost:3000",
"is_active": true
}
]
🧪 Test
Frontend'den Test:
// Next.js veya React'ten
fetch('https://goauth.beyhano.net.tr/v1/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'test@example.com',
password: 'password123'
})
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
Browser Console'dan Test:
// Preflight request'i test et
fetch('https://goauth.beyhano.net.tr/v1/auth/login', {
method: 'OPTIONS',
headers: {
'Access-Control-Request-Method': 'POST',
'Access-Control-Request-Headers': 'content-type'
}
})
.then(res => {
console.log('Preflight Status:', res.status); // 204 olmalı
console.log('CORS Headers:', res.headers);
});
📊 CORS Headers Özeti
Request başarılı olduğunda aşağıdaki header'lar dönmeli:
Access-Control-Allow-Origin: https://nextgo.beyhano.net.tr
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Max-Age: 86400
🔒 Güvenlik Notları
Whitelist Best Practices:
✅ Yapın:
- Sadece güvendiğiniz domain'leri ekleyin
- Her environment için ayrı origin kullanın
- HTTPS kullanın (production için)
- Description field'ını doldurun
❌ Yapmayın:
- Wildcard (
*) kullanmayın - HTTP kullanmayın (production'da)
- Herkese açık domain eklemeyin
- Test domain'lerini production'da bırakmayın
Blacklist Kullanımı:
Şüpheli veya kötü niyetli origin'leri blacklist'e ekleyin:
curl -X POST https://goauth.beyhano.net.tr/v1/settings/cors/blacklist \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"origin": "https://malicious-site.com",
"reason": "Security threat detected"
}'
🎯 Troubleshooting
Hala 403 alıyorsanız:
- Whitelist'te var mı kontrol edin:
curl -X GET https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" | jq '.[] | .origin'
-
Origin tam eşleşiyor mu?
- ✅
https://nextgo.beyhano.net.tr(doğru) - ❌
https://nextgo.beyhano.net.tr/(slash yanlış) - ❌
http://nextgo.beyhano.net.tr(http/https farkı)
- ✅
-
is_active = true mi?
curl -X GET https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" | jq '.[] | {origin, is_active}'
- Redis cache'i temizleyin:
docker exec -it gauth_redis redis-cli
> DEL cors:whitelist
> DEL cors:blacklist
> exit
- Container'ı restart edin:
docker restart app_auth_central
📖 İlgili Dokümantasyon
- CORS API Detayları:
CORS_API_DOCUMENTATION.md - Test Script:
test-cors-api.sh - Deployment Guide:
DOKPLOY_DEPLOYMENT.md
✅ Checklist
Production'a geçmeden önce:
- Admin kullanıcı oluşturuldu
- Production frontend origin whitelist'e eklendi
- Development origin whitelist'e eklendi (opsiyonel)
- Whitelist doğrulandı (GET request)
- Frontend'den test edildi
- OPTIONS preflight request test edildi
- Browser console'da CORS hatası yok
- Redis cache çalışıyor
- Swagger'da CORS endpoints görünüyor
CORS 403 hatası çözüldü! ✅