Files
AuthCentral/DATABASE_DRIVEN_CORS.md
Beyhan Oğur 8b1fbdee99 first commit
2026-04-26 21:37:58 +03:00

9.3 KiB
Raw Blame History

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_active toggle 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/ vs https://domain.com)
  • Forget to activate origins (is_active = false)
  • Delete without backing up (use is_active = false instead)

🚨 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!