Ana içeriğe geç

JWT ve Yetkilendirme Akışı

Bu sayfa, Qapu API Servisi içinde önerilen JWT doğrulama yaklaşımını, Redis destekli yetki çözümünü ve DB doğruluk katmanı ilişkisini tanımlar.

Temel ilke şudur:

  • JWT, kullanıcının kim olduğunu ve oturum bağlamını doğrular.
  • Redis, hızlı authz lookup ve session kontrol katmanıdır.
  • DB, kalıcı ve authoritative source olarak kalır.

Kısaca: JWT ile kimliği doğrula, Redis ile hızlı yetki çöz, DB ile doğruluğu koru.

Hedef Mimari

JWT İçeriği Nasıl Olmalı?

JWT içinde yalnız request başlatmak için gerekli ve görece yavaş değişen alanlar taşınmalıdır.

Önerilen access token payload:

{
"sub": 123,
"sid": "sess_abc123",
"role_id": 31,
"tenant_id": 45,
"auth_version": 7,
"iat": 1760000000,
"exp": 1760003600
}

JWT Alanları

AlanZorunluAçıklama
subEvetKullanıcı kimliği
sidEvetSession / oturum kimliği
role_idEvetHızlı genel bağlam için rol kimliği
tenant_idOpsiyonelTenant-scoped yapılarda tenant kimliği
auth_versionEvetYetki/snapshot versiyonu
iatEvetToken üretim zamanı
expEvetToken bitiş zamanı

JWT İçine Ne Konmamalı?

Aşağıdaki alanlar doğrudan JWT içine gömülmemelidir:

  • tüm permission listesi
  • tüm authority listesi
  • tüm cihaz erişimleri
  • permission history
  • hızlı değişen device-scoped yetki setleri

Gerekçe:

  • token şişer
  • revoke zorlaşır
  • yetki değişince stale token riski artar
  • device-scoped permission modeli çok statik hale gelir

Authentication ve Authorization Ayrımı

Authentication

Soru: bu kullanıcı kim?

Cevap katmanı:

  • JWT signature doğrulama
  • token expiry doğrulama
  • session aktiflik kontrolü

Authorization

Soru: bu kullanıcı bu işlemi yapabilir mi?

Cevap katmanı:

  • Redis auth context
  • Redis device-scoped permission projection
  • gerekirse DB fallback

Kural: JWT valid olması, işlemi yapmaya otomatik izin vermez.

Önerilen Session Katmanı

JWT stateless olsa da session kontrolü Redis üzerinden tutulmalıdır.

Önerilen key:

  • session:{sid}

Örnek payload:

{
"user_id": 123,
"status": "active",
"auth_version": 7,
"created_at": "2026-04-16T12:00:00Z",
"expire_at": "2026-04-16T13:00:00Z"
}

Bu key şu amaçlarla kullanılır:

  • logout
  • force logout
  • session revoke
  • eski token versiyonunu reddetme

Request Akışı

Genel Endpointler

Örnek:

  • kullanıcı profili getir
  • panel özeti al
  • rapor listesi getir

Akış:

  1. JWT doğrulanır.
  2. session:{sid} kontrol edilir.
  3. user:{user_id}:auth-context Redis'ten okunur.
  4. Kullanıcı aktifse domain servise geçilir.
  5. Redis miss durumunda DB fallback + cache rebuild uygulanır.

Device-scoped Endpointler

Örnek:

  • pompa başlat
  • pompa durdur
  • not ekle
  • cihaz raporlarını görüntüle

Akış:

  1. JWT doğrulanır.
  2. session:{sid} kontrol edilir.
  3. user:{user_id}:auth-context okunur.
  4. device:{device_id}:user:{user_id}:authz key'i okunur.
  5. Gerekli permission code var mı kontrol edilir.
  6. Varsa işlem geçer, yoksa FORBIDDEN dönülür.
  7. Redis miss durumunda DB join çözümü ile projection rebuild edilir.

Kritik Güvenlik Kuralı

Aşağıdaki işlemler JWT geçerli olsa bile ayrıca server-side authz kontrolü gerektirir:

  • pump.start
  • pump.stop
  • device.settings.change
  • finansal silme/güncelleme işlemleri
  • authority update
  • permission grant / revoke

Bu işlemlerde yalnız token içindeki role veya claim bilgisine güvenilmez.

auth_version Neden Gerekli?

auth_version, kullanıcının yetki bağlamı değiştiğinde eski token'ları kontrol altına almak için kullanılır.

Örnek durumlar:

  • role değişti
  • user status değişti
  • authority değişti
  • permission set değişti

Akış:

  1. DB/Redis tarafında kullanıcının auth_version değeri artar.
  2. Eski token eski auth_version ile gelirse session/auth check aşamasında reddedilir veya refresh zorlanır.

Bu yaklaşım JWT stale riskini ciddi biçimde azaltır.

Redis Auth Cache Katmanı

API Servisi aşağıdaki Redis key seti ile çalışmalıdır:

  • session:{sid}
  • user:{user_id}:auth-context
  • authority:{authority_id}
  • authority:{authority_id}:permissions
  • device:{device_id}:user:{user_id}:authz

Detaylı key sözleşmeleri için bkz:

TTL Yaklaşımı

Önerilen TTL aralıkları:

KeyTTL Önerisi
session:{sid}access token ömrü kadar veya biraz uzun
user:{user_id}:auth-context10m - 30m
authority:{authority_id}5m - 15m
authority:{authority_id}:permissions5m - 15m
device:{device_id}:user:{user_id}:authz2m - 10m

Kural: TTL tek güvence değildir, explicit invalidation ile birlikte kullanılmalıdır.

Invalidation Kuralları

User değişirse

Örnek:

  • role_id
  • status_id
  • is_deleted

Invalidation:

  • user:{user_id}:auth-context
  • ilişkili device-scoped projection keyleri
  • gerekiyorsa session version kontrolü

Authority değişirse

Örnek:

  • owner
  • is_active
  • device_id

Invalidation:

  • authority:{authority_id}
  • device:{device_id}:user:{user_id}:authz

Authority permissions değişirse

Örnek:

  • permission eklendi
  • permission kaldırıldı
  • permission pasif yapıldı

Invalidation:

  • authority:{authority_id}:permissions
  • device:{device_id}:user:{user_id}:authz

Sonuç

Önerilen model şudur:

  • JWT ile kullanıcı kimliği doğrulanır.
  • Redis ile hızlı authz lookup yapılır.
  • DB authoritative source olarak korunur.
  • Yetki kararları gerektiğinde device-scoped projection üzerinden çözülür.

Bu yaklaşım hem performanslı hem de revoke / stale token / granular permission gibi konularda yönetilebilir bir yapı sağlar.