first commit
This commit is contained in:
417
belgeler/DATABASE_DRIVEN_CORS.md
Normal file
417
belgeler/DATABASE_DRIVEN_CORS.md
Normal file
@@ -0,0 +1,417 @@
|
||||
# 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
|
||||
|
||||
```sql
|
||||
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:**
|
||||
```sql
|
||||
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
|
||||
|
||||
```sql
|
||||
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:**
|
||||
```sql
|
||||
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:
|
||||
|
||||
```go
|
||||
// 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
|
||||
|
||||
```go
|
||||
// Create/Update/Delete sonrası:
|
||||
cacheService.InvalidateCorsWhitelist()
|
||||
cacheService.InvalidateCorsBlacklist()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎬 Gerçek Akış Örneği
|
||||
|
||||
### Senaryo: Frontend Login Request
|
||||
|
||||
**1. Frontend Request:**
|
||||
```http
|
||||
POST https://goauth.beyhano.net.tr/v1/auth/login
|
||||
Origin: https://nextgo.beyhano.net.tr
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**2. Backend - Dynamic CORS Middleware:**
|
||||
```go
|
||||
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
|
||||
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:
|
||||
```bash
|
||||
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:**
|
||||
```sql
|
||||
-- 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:
|
||||
```bash
|
||||
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:**
|
||||
```sql
|
||||
UPDATE cors_whitelists
|
||||
SET is_active = false, updated_at = NOW()
|
||||
WHERE id = '{id}';
|
||||
|
||||
-- Redis cache invalidated
|
||||
DEL cors:whitelist
|
||||
```
|
||||
|
||||
#### Delete:
|
||||
```bash
|
||||
curl -X DELETE https://goauth.beyhano.net.tr/v1/settings/cors/whitelist/{id} \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
**Database Impact:**
|
||||
```sql
|
||||
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):
|
||||
```sql
|
||||
SELECT origin, is_active, created_at
|
||||
FROM cors_whitelists
|
||||
WHERE is_active = true
|
||||
ORDER BY created_at DESC;
|
||||
```
|
||||
|
||||
### Check Current Blacklists (Database):
|
||||
```sql
|
||||
SELECT origin, reason, is_active, created_at
|
||||
FROM cors_blacklists
|
||||
WHERE is_active = true
|
||||
ORDER BY created_at DESC;
|
||||
```
|
||||
|
||||
### Check Redis Cache:
|
||||
```bash
|
||||
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:
|
||||
```bash
|
||||
# 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:**
|
||||
```bash
|
||||
# 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:**
|
||||
```bash
|
||||
# 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!**
|
||||
Reference in New Issue
Block a user