9.3 KiB
9.3 KiB
Database-Driven CORS Sistemi
🎯 Sistem Mimarisi
AuthCentral tamamen database-driven CORS sistemi kullanır. Hardcoded origin'ler yok!
┌─────────────┐
│ Frontend │
│ Request │
└──────┬──────┘
│
▼
┌─────────────────────────────────────┐
│ Dynamic CORS Middleware │
│ (middlewares/dynamic_cors.go) │
└──────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Settings Service │
│ IsOriginAllowed(origin) │
└──────┬──────────────────────────────┘
│
├─────► 1. Redis Cache Check
│ └─► Hit? Return cached result
│
├─────► 2. PostgreSQL Blacklist Check
│ └─► Is origin blacklisted?
│ └─► Yes? DENY (403)
│
└─────► 3. PostgreSQL Whitelist Check
└─► Is origin whitelisted?
├─► Yes? ALLOW (200/204)
└─► No? DENY (403)
📊 Database Tables
1. cors_whitelists
CREATE TABLE cors_whitelists (
id UUID PRIMARY KEY,
origin VARCHAR(255) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT true,
created_by VARCHAR(255),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Örnek:
INSERT INTO cors_whitelists (origin, description, is_active)
VALUES
('https://nextgo.beyhano.net.tr', 'Production frontend', true),
('http://localhost:3000', 'Development', true);
2. cors_blacklists
CREATE TABLE cors_blacklists (
id UUID PRIMARY KEY,
origin VARCHAR(255) UNIQUE NOT NULL,
reason TEXT,
is_active BOOLEAN DEFAULT true,
created_by VARCHAR(255),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Örnek:
INSERT INTO cors_blacklists (origin, reason, is_active)
VALUES
('https://malicious-site.com', 'Security threat', true),
('https://spam-domain.com', 'Spam attempts', true);
🔄 CORS Check Flow
Request Geldiğinde:
// 1. Origin header'ı al
origin := c.Request.Header.Get("Origin")
// Örnek: "https://nextgo.beyhano.net.tr"
// 2. Redis cache'e bak
cached, err := cacheService.GetCorsWhitelist()
if err == nil && cached != nil {
// Cache hit! Database'e gitmeden cevap ver
return checkOriginInList(origin, cached)
}
// 3. Cache miss - Database'den oku
// 3a. Önce blacklist kontrol et
blacklists := database.DB.Where("is_active = true").Find(&CorsBlacklist{})
for _, blocked := range blacklists {
if blocked.Origin == origin {
return false, nil // ❌ DENY - Blacklist'te var
}
}
// 3b. Sonra whitelist kontrol et
whitelists := database.DB.Where("is_active = true").Find(&CorsWhitelist{})
for _, allowed := range whitelists {
if allowed.Origin == origin || allowed.Origin == "*" {
return true, nil // ✅ ALLOW - Whitelist'te var
}
}
// 3c. İkisinde de yok
return false, nil // ❌ DENY - Listelenmeyen origin
⚡ Redis Cache
Cache Keys:
- Whitelist:
cors:whitelist - Blacklist:
cors:blacklist
Cache TTL:
- 1 saat (3600 saniye)
Cache Invalidation:
Cache otomatik olarak temizlenir:
- ✅ Whitelist Create/Update/Delete
- ✅ Blacklist Create/Update/Delete
// Create/Update/Delete sonrası:
cacheService.InvalidateCorsWhitelist()
cacheService.InvalidateCorsBlacklist()
🎬 Gerçek Akış Örneği
Senaryo: Frontend Login Request
1. Frontend Request:
POST https://goauth.beyhano.net.tr/v1/auth/login
Origin: https://nextgo.beyhano.net.tr
Content-Type: application/json
2. Backend - Dynamic CORS Middleware:
origin := "https://nextgo.beyhano.net.tr"
// Cache check
cached := redis.Get("cors:whitelist")
// Result: nil (cache miss)
// Database check
blacklisted := checkBlacklist(origin)
// Result: false (not blacklisted)
whitelisted := checkWhitelist(origin)
// Result: true (found in database!)
// Set CORS headers
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Credentials", "true")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
// Cache for next request
redis.Set("cors:whitelist", whitelists, 1*time.Hour)
3. Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://nextgo.beyhano.net.tr
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 86400
🛠️ CRUD Operations
Whitelist Management
Create:
curl -X POST https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"origin": "https://app.example.com",
"description": "Customer app"
}'
Database Impact:
-- Immediately inserted
INSERT INTO cors_whitelists (origin, description, is_active)
VALUES ('https://app.example.com', 'Customer app', true);
-- Redis cache invalidated
DEL cors:whitelist
Result: Next request will read fresh data from database
Update:
curl -X PUT https://goauth.beyhano.net.tr/v1/settings/cors/whitelist/{id} \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"is_active": false
}'
Database Impact:
UPDATE cors_whitelists
SET is_active = false, updated_at = NOW()
WHERE id = '{id}';
-- Redis cache invalidated
DEL cors:whitelist
Delete:
curl -X DELETE https://goauth.beyhano.net.tr/v1/settings/cors/whitelist/{id} \
-H "Authorization: Bearer $TOKEN"
Database Impact:
DELETE FROM cors_whitelists WHERE id = '{id}';
-- Redis cache invalidated
DEL cors:whitelist
📈 Performance
Without Cache:
Request → Database Query → Response
Time: ~50-100ms
With Cache (after 1st request):
Request → Redis Cache → Response
Time: ~1-5ms
Improvement: 10-50x faster! 🚀
🔍 Debugging
Check Current Whitelists (Database):
SELECT origin, is_active, created_at
FROM cors_whitelists
WHERE is_active = true
ORDER BY created_at DESC;
Check Current Blacklists (Database):
SELECT origin, reason, is_active, created_at
FROM cors_blacklists
WHERE is_active = true
ORDER BY created_at DESC;
Check Redis Cache:
docker exec -it gauth_redis redis-cli
# View whitelist cache
GET cors:whitelist
# View blacklist cache
GET cors:blacklist
# Clear cache (force database reload)
DEL cors:whitelist
DEL cors:blacklist
# Check TTL
TTL cors:whitelist
Backend Logs:
# Watch CORS requests
docker logs -f app_auth_central | grep -i "cors\|origin"
🎯 Best Practices
✅ DO:
- Add production origins to whitelist ASAP
- Use HTTPS origins in production
- Add descriptive comments for each origin
- Use
is_activetoggle instead of delete (for audit) - Monitor blacklist for security threats
❌ DON'T:
- Use wildcard (
*) in production (security risk) - Mix HTTP/HTTPS (browser will block)
- Add trailing slashes (
https://domain.com/vshttps://domain.com) - Forget to activate origins (
is_active = false) - Delete without backing up (use
is_active = falseinstead)
🚨 Common Issues
Issue 1: Still Getting 403
Check:
# 1. Is origin in whitelist?
curl -X GET https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" | jq '.[] | .origin'
# 2. Is origin active?
curl -X GET https://goauth.beyhano.net.tr/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" | jq '.[] | select(.origin=="https://yourorigin.com") | .is_active'
# 3. Clear cache
docker exec -it gauth_redis redis-cli DEL cors:whitelist
# 4. Restart container
docker restart app_auth_central
Issue 2: Origin Not Matching
Problem: Origin case-sensitive ve exact match!
❌ Wrong:
Whitelist: https://domain.com/
Request: https://domain.com (no trailing slash)
✅ Correct:
Whitelist: https://domain.com
Request: https://domain.com
Issue 3: Localhost Not Working
Add localhost variants:
# Add all localhost variants
curl -X POST $BACKEND/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" \
-d '{"origin":"http://localhost:3000"}'
curl -X POST $BACKEND/v1/settings/cors/whitelist \
-H "Authorization: Bearer $TOKEN" \
-d '{"origin":"http://127.0.0.1:3000"}'
📚 Summary
AuthCentral CORS Sistemi:
✅ Tamamen Database-Driven
- PostgreSQL tables (cors_whitelists, cors_blacklists)
- Real-time CRUD API
- No hardcoded origins
✅ Redis Cache
- 1 hour TTL
- Auto invalidation
- 10-50x performance boost
✅ Dynamic Middleware
- Runtime database check
- Blacklist → Whitelist priority
- Preflight (OPTIONS) support
✅ Admin Control
- REST API for management
- Active/Inactive toggle
- Audit trail (created_by, timestamps)
Configuration Files: ZERO 🎉 All managed via API!