Kimlik Doğrulama (Authentication)
JWT Token Yapısı
Access Token (30 dakika)
{"exp": 1234567890, "sub": "user-uuid", "tenant_id": "tenant-uuid", "type": "access"}
Refresh Token (7 gün)
{"exp": 1234567890, "sub": "user-uuid", "tenant_id": "tenant-uuid", "type": "refresh"}
Login Akışı
POST /api/auth/login
Body: {"email": "user@example.com", "password": "..."}
Response: {"access_token": "...", "refresh_token": "..."}
Token Yenileme
POST /api/auth/refresh
Body: {"refresh_token": "..."}
Response: {"access_token": "new-token"}
Password Hashing
- Algoritma: pbkdf2_sha256 / bcrypt
passlib[bcrypt]kütüphanesi
Dependency Injection
async def get_current_user(token: str = Depends(HTTPBearer())):
payload = decode_token(token)
user = await db.get(User, payload["sub"])
permissions = load_permissions(user)
return CurrentUser(id=user.id, tenant_id=user.tenant_id, permissions=permissions)
Token İmzalama
| Parametre | Değer |
|---|---|
| Algoritma | HS256 (HMAC with SHA-256) |
| Secret Key | SECRET_KEY environment değişkeni (minimum 32 karakter) |
| Kaynak Dosya | backend/app/core/security/auth.py |
Token imzalama için kullanılan secret key, .env dosyasında SECRET_KEY olarak tanımlanır. Bu değerin kriptografik olarak güçlü ve en az 32 karakter uzunluğunda olması zorunludur. Secret key değiştiğinde mevcut tüm token'lar geçersiz hale gelir.
Token Yenileme ve İptal
Yenileme Akışı
- Access token süresi dolduğunda (30 dakika) client HTTP 401 alır
- Client, refresh token ile
POST /api/auth/refreshendpoint'ine istek gönderir - Backend refresh token'ı doğrular ve yeni access token döner
- Refresh token'ın da süresi dolduysa (7 gün) kullanıcının yeniden giriş yapması gerekir
Stateless JWT Yapısı
- Refresh token'lar veritabanında saklanmaz (stateless JWT)
- Token iptali için blacklist mekanizması yoktur
- Bu nedenle token sürelerinin kısa tutulması kritiktir (access: 30dk, refresh: 7 gün)
Token Geçersiz Kılma
- Şifre değişikliğinde mevcut token'lar doğal süreleri dolana kadar geçerli kalır
- Acil durumda tüm token'ları geçersiz kılmak için
SECRET_KEYrotasyonu yapılmalıdır - SECRET_KEY rotasyonu tüm kullanıcıların token'larını geçersiz kılar — dikkatli kullanılmalıdır
CORS Yapılandırması
FastAPI CORSMiddleware ile cross-origin istekler kontrol altına alınmıştır.
Backend Ayarları
app.add_middleware(
CORSMiddleware,
allow_origins=["https://enerji.kepmark.com"], # Frontend domain
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Next.js Proxy (Same-Origin)
Frontend'den API'ye yapılan istekler next.config.js içindeki rewrites ile proxy'lenir. Bu sayede tarayıcı tarafında same-origin politikası sağlanır:
// next.config.js
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'http://backend:8000/api/:path*',
},
];
}
Bu yapılandırma sayesinde frontend /api/* isteklerini doğrudan kendi origin'inden yapar, CORS sorunları ortadan kalkar.
Rate Limiting
Kimlik doğrulama endpoint'leri Nginx katmanında rate limiting ile korunmaktadır.
| Endpoint | Limit | Açıklama |
|---|---|---|
POST /api/auth/login | 5 istek/dakika | Brute-force saldırı koruması |
POST /api/auth/refresh | 5 istek/dakika | Token yenileme kötüye kullanım koruması |
/api/* (genel) | 30 istek/saniye | Genel API koruması |
Aşım Davranışı
- HTTP 429 Too Many Requests status kodu döner
Retry-Afterheader'ı ile beklenmesi gereken süre belirtilir- Client tarafında exponential backoff stratejisi önerilir
Nginx Yapılandırma Örneği
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
location /api/auth/login {
limit_req zone=login burst=3 nodelay;
proxy_pass http://backend;
}
location /api/ {
limit_req zone=api burst=50 nodelay;
proxy_pass http://backend;
}