Bölüm 5 / 11
JWT
Yapı, imza, doğrulama, saklama, süre ve yenileme.
15 dakikalık okuma
JWT — JSON Web Token — kimlik bilgisini imzalı olarak taşıyan, kendi kendini doğrulayabilen bir jeton biçimidir. Popülerdir, çünkü sunucuda oturum deposu gerektirmez. Aynı sebeple tehlikelidir: verilen bir jetonu geri almanın kolay bir yolu yoktur. Bu ders üç şeyi net yapıyor — jetonun içinde tam olarak ne olduğu, doğrulamanın hangi kontrollerden oluştuğu (eksik yapılan kontroller gerçek zafiyetlerdir), ve 11-10, 11-11 ile 12-12'de üç kez ileriye gönderdiğimiz sorunun cevabı: jeton nerede saklanır?
01Ne öğreneceksin
- JWT'nin üç parçası, base64url kodlama şifreleme değildir, JWS ile JWE farkı
- HS256 ile RS256/ES256 arasındaki seçim: kim imzalıyor, kim doğruluyor?
- Klasik saldırılar:
alg: none, algoritma karıştırma,kidenjeksiyonu, zayıf HMAC sırrı - Doğrulama kontrol listesi: imza, algoritma beyaz listesi,
exp/nbfve saat kayması,iss,aud,typ - İptal problemi: "durumsuz"un gerçek maliyeti ve dört çözüm kalıbı
- Yenileme jetonu, dönüşüm (rotation) ve yeniden kullanım tespiti
- Nerede saklanır kararı: localStorage ↔ httpOnly çerez ↔ BFF; ve "bellekte tut + sessiz yenile" deseni
02Jetonun içinde ne var?
JWT üç parçadır, noktayla ayrılır ve her parça base64url ile kodlanmıştır:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJzdWIiOiI0MiIsImV4cCI6MTc1NTAwMDAwMH0 . 3vQ8k_1nZ...
└──────── başlık (header) ────────┘ └──── yük (payload) ────┘ └── imza ──┘
Başlık: { "alg": "HS256", "typ": "JWT", "kid": "2026-01" }
Yük: { "sub": "42", "iss": "https://kimlik.ornek.gov.tr", "aud": "basvuru-api",
"exp": 1755000000, "iat": 1754996400, "roller": ["basvuru-sahibi"] }
İmza: HMAC-SHA256( base64url(başlık) + "." + base64url(yük), SIR )
En kritik cümle: base64url bir kodlamadır, şifreleme değildir.
Jetonu eline geçiren herkes yükü okur — tarayıcı konsolunda tek satırla çözülür.
Buradan iki mutlak kural çıkar: JWT'ye parola, kimlik numarası, sağlık verisi
gibi hiçbir hassas bilgi konmaz; ve jeton, 12-11'de öğrendiğin üzere
loglara yazılmaz (redaksiyon listesine authorization başlığı
dâhildir).
İmza gizlilik değil bütünlük ve kimlik sağlar: içeriği okuyabilirsin ama değiştiremezsin, çünkü imza tutmaz. Standartta bu imzalı biçime JWS denir ve pratikte "JWT" dendiğinde kastedilen budur. İçeriği gerçekten gizlemek gerekiyorsa JWE (şifrelenmiş) biçimi vardır; nadiren kullanılır, çünkü hassas veriyi jetona koymamak daha basit bir çözümdür.
Standart iddialar (claim) kısaltmalarıyla bilinir ve sınavda sorulur:
iss (veren), sub (özne — kullanıcı kimliği),
aud (hedef kitle — jetonun kimin için olduğu), exp
(bitiş zamanı), nbf (bu zamandan önce geçersiz), iat
(veriliş zamanı), jti (jeton kimliği — tekrar tespiti ve kara liste
için). Bunların üzerine uygulamaya özel iddialar eklenir (rol, kurum, kapsam).
03Hangi algoritma: HS256 mi, RS256 mı?
| HS256 (HMAC — simetrik) | RS256 / ES256 (asimetrik) | |
|---|---|---|
| Anahtar | Tek paylaşılan sır | Özel anahtar imzalar, açık anahtar doğrular |
| Kim imzalayabilir | Sırrı bilen herkes | Yalnızca özel anahtarın sahibi |
| Doğrulayıcıya ne verilir | Sırrın kendisi (yani imzalama yetkisi) | Yalnızca açık anahtar — yayınlanabilir |
| Uygun olduğu yer | Jetonu üreten ve doğrulayan aynı uygulama | Bir kimlik sağlayıcı, çok sayıda bağımsız API |
| Hız | Daha hızlı | Doğrulama hızlı, imzalama görece yavaş |
Karar kuralı tek cümledir: doğrulayan taraf sayısı birden fazlaysa asimetrik kullan. HS256'da her doğrulayıcıya sırrı vermek zorunda kalırsın ve sırrı bilen her servis jeton üretebilir — yani beş mikroservise sırrı dağıtmak, beşine de kimlik sağlayıcı yetkisi vermektir. En az yetki ilkesinin doğrudan ihlalidir. Asimetrikte açık anahtar herkese açık bir uçtan (JWKS — 6. derste) yayınlanır ve doğrulayıcılar onu çeker.
Anahtar yönetimi iki ayrıntı ister. Anahtar döndürme: başlıktaki
kid alanı hangi anahtarın kullanıldığını söyler; sunucu birden çok
anahtarı aynı anda geçerli tutarak eski jetonların ömrü dolana kadar kesintisiz
geçiş yapar. Sır gücü: HS256 kullanıyorsan sır, en az imza uzunluğu kadar
(256 bit) rastgele olmalıdır. "gizli", "secret123" gibi
sırlar çevrim dışı kaba kuvvetle saniyeler içinde bulunur — üstelik saldırgan bunu
denemek için sunucuna hiç dokunmaz, elindeki tek jeton yeter.
04Klasik saldırılar
1) alg: none. Standart, "imzasız jeton" için
none algoritmasını tanımlar. Erken kütüphaneler jetonun başlığındaki
alg alanına bakıp ona göre davranıyordu; saldırgan başlığı
{"alg":"none"} yapıp imzayı silince jeton geçerli sayılıyordu.
Kök hata mimaridir: jetonu gönderen tarafın, nasıl doğrulanacağını söylemesine
izin verilmiştir.
2) Algoritma karıştırma (RS256 → HS256). Daha incelikli olanı budur.
Sunucu RS256 bekliyor ve doğrulama için açık anahtarı kullanıyor. Saldırgan
başlığı HS256 olarak değiştirir ve jetonu, herkese açık olan o açık
anahtarı HMAC sırrı olarak kullanarak imzalar. Kütüphane "alg HS256 diyor" deyip
elindeki anahtarı simetrik sır sanarak doğrular — ve imza tutar.
// ZAFİYETLİ: algoritma jetondan okunuyor
jwt.verify(jeton, anahtar);
// DOĞRU: algoritma ve hedef kitle SUNUCU tarafından dayatılıyor
jwt.verify(jeton, acikAnahtar, {
algorithms: ["RS256"], // beyaz liste — jetonun dediği umursanmaz
issuer: "https://kimlik.ornek.gov.tr",
audience: "basvuru-api",
clockTolerance: 30, // saniye; sunucu saatleri arasındaki kayma payı
});
// .NET karşılığı
new TokenValidationParameters {
ValidateIssuerSigningKey = true,
ValidateIssuer = true, ValidIssuer = "https://kimlik.ornek.gov.tr",
ValidateAudience = true, ValidAudience = "basvuru-api",
ValidateLifetime = true, ClockSkew = TimeSpan.FromSeconds(30), // varsayılan 5 DAKİKA'dır
ValidAlgorithms = new[] { SecurityAlgorithms.RsaSha256 }
};
3) kid enjeksiyonu. kid alanı anahtarı seçmek
için kullanılır. Uygulama bu değeri doğrudan bir dosya yoluna ya da SQL sorgusuna
koyarsa, saldırgan "kid": "../../dev/null" ya da bir SQL parçası
yazarak doğrulamayı kendi kontrol ettiği bir anahtara yönlendirebilir. Kural:
kid bir beyaz listeye karşı eşlenir, asla dinamik bir kaynağa
doğrudan verilmez — 9. dersteki "dinamik sütun adı beyaz listesi" kuralının aynısı.
4) Doğrulamayı hiç yapmamak. Sahada en sık görülen "saldırı" budur:
jwt.decode() ile jwt.verify() karıştırılır.
decode yalnızca base64'ü çözer, imzayı kontrol etmez. Kod
çalışır, testler geçer, jeton "okunur" — ve herkes istediği yükü yazabilir.
05Doğrulama kontrol listesi
Doğrulama tek bir işlem değil, bir kontroller kümesidir. Eksik bırakılan her madde gerçek bir zafiyettir:
- İmza geçerli mi — doğru anahtarla, sunucunun dayattığı algoritmayla.
expgeçmiş mi — venbfgelmiş mi. Dağıtık sistemlerde küçük bir saat kayması toleransı gerekir (30 saniye tipiktir). .NET'in varsayılanı 5 dakikadır ve bu, "süresi dolmuş jeton hâlâ çalışıyor" şaşkınlığının klasik sebebidir — açıkça kısaltılır.issbeklediğim veren mi — birden çok kimlik sağlayıcı varsa şart.audben miyim — en sık atlanan kontrol. Atlanırsa, başka bir API için verilmiş geçerli bir jeton seninkinde de çalışır; o API'nin sahibi (ya da o API'ye jeton alabilen herkes) senin sisteminde kullanıcı olur. Buna jeton yeniden kullanımı / karıştırma denir.typve jeton türü — erişim jetonu ile kimlik jetonu ya da yenileme jetonu birbirinin yerine kullanılmamalıdır (6. dersin konusu).- Yetki iddiaları — rol/kapsam kontrolü ayrı bir adımdır; jeton geçerli olması onu yetkili yapmaz. 3. dersteki AuthN/AuthZ ayrımı burada da geçerlidir, ve nesne düzeyi kontrol (IDOR) yine ayrıca yapılır.
Pratik not: bu kontrolleri elle yazmazsın. ASP.NET Core'da
AddJwtBearer, Node'da olgun bir kütüphane bunları yapar — senin işin
parametreleri doğru vermek ve varsayılanları bilmektir. Kendi JWT doğrulama
kodunu yazmak, bu konudaki en güvenilir kıdemsizlik göstergesidir.
06İptal problemi: "durumsuz"un gerçek bedeli
JWT'nin satış argümanı şudur: sunucu her istekte veritabanına gitmez, imzayı
doğrular ve devam eder. Bunun karşılığında ödediğin bedel nettir: verilmiş bir
jetonu geri alamazsın. Kullanıcı çıkış yaptı, hesabı askıya alındı, rolü
düşürüldü, parolası ele geçirildiği için değiştirildi — jeton hâlâ geçerlidir ve
exp gelene kadar çalışır.
Dört çözüm kalıbı vardır ve hepsi "durumsuzluk"tan bir miktar taviz verir:
| Kalıp | Nasıl | Bedeli |
|---|---|---|
| Kısa ömür + yenileme | Erişim jetonu 5-15 dk; yenileme jetonu uzun ömürlü ve sunucuda kayıtlı | En yaygın çözüm; iptal anında değil, en fazla bir jeton ömrü gecikir |
| Kara liste | İptal edilen jti'ler bir depoda (Redis) tutulur, her istekte bakılır | Durumsuzluk biter — her istekte arama; ama depo yalnızca iptal edilenleri tutar, küçüktür |
| Sürüm iddiası | Jetona tv (token version) konur; kullanıcı kaydında da bir sürüm sayacı vardır, eşleşmezse jeton geçersiz | Kullanıcı kaydı okunur (çoğu istek zaten okur); parola değişiminde sayacı artırmak tüm oturumları anında düşürür |
| Introspection | Kaynak sunucu, kimlik sağlayıcıya "bu jeton hâlâ geçerli mi" diye sorar | Her istekte ağ çağrısı; genelde önbellekle yumuşatılır (6. ders) |
Kıdemli sonuç şudur: pratikte tam durumsuz bir kimlik sistemi nadiren kabul edilebilir. "Anında çıkış" ve "hesabı anında askıya al" gereksinimleri neredeyse her kurumsal projede vardır. Yaygın ve dengeli çözüm: kısa ömürlü erişim jetonu + sunucuda kayıtlı yenileme jetonu + kritik olaylarda sürüm iddiası. Bu bileşimi tarif edebilmek, JWT'yi "biliyorum" ile "kullanmışım" arasındaki farktır.
07Yenileme jetonu ve dönüşüm
Yenileme jetonu (refresh token), erişim jetonunun süresi dolduğunda yenisini almak için kullanılan uzun ömürlü bir kimlik bilgisidir. Erişim jetonundan farkı şudur: yalnızca kimlik sağlayıcıya sunulur, API'lere değil; ve sunucuda kayıtlıdır, dolayısıyla iptal edilebilir.
Uzun ömürlü olması onu değerli bir hedef yapar, bu yüzden iki mekanizma standart hâline geldi:
- Dönüşüm (rotation): her yenileme isteğinde eski yenileme jetonu geçersizleşir ve yenisi verilir. Böylece bir jeton en fazla bir kez kullanılır.
- Yeniden kullanım tespiti: geçersizleşmiş bir yenileme jetonu tekrar sunulursa, bu ya bir kopyanın çalındığı ya da meşru istemcinin bir yarışa girdiği anlamına gelir. Güvenli davranış: o kullanıcıya ait tüm jeton ailesini iptal et ve kullanıcıyı yeniden giriş yapmaya zorla. Saldırgan çalıntı jetonu kullandığı anda meşru kullanıcı düşer ve olay görünür olur.
Giriş → erişim(10 dk) + yenileme R1
R1 kullan → erişim(10 dk) + yenileme R2, R1 GEÇERSİZ
R2 kullan → erişim(10 dk) + yenileme R3, R2 GEÇERSİZ
R1 tekrar gelirse → ALARM: R1/R2/R3 zincirinin tamamı iptal, kullanıcı düşürülür
Üç ek kural: yenileme jetonunun bir mutlak ömrü olur (ne kadar döndürülürse döndürülsün 30 gün sonra biter); istemciye bağlanır (hangi istemci, hangi cihaz); ve saklandığı yer erişim jetonundan daha korunaklı olmalıdır — çünkü daha uzun yaşar.
08Jeton nerede saklanır? — üç kez ertelenen karar
11-10, 11-11 ve 12-12'de bu soruyu bu derse bırakmıştık. Cevap bir tercih tablosudur ve her seçenekte bir risk kalır; "tamamen güvenli" bir seçenek yoktur.
| Seçenek | Nasıl | Ana risk | Ne zaman |
|---|---|---|---|
localStorage | JS okur, Authorization başlığına koyar | XSS = jeton çalınır ve sunucuya taşınabilir; CSRF yok | Riski kabul edilmiş iç araçlar; genel öneri değildir |
httpOnly çerez | Tarayıcı otomatik gönderir, JS göremez | CSRF (4. dersin savunmaları gerekir); XSS'te jeton okunamaz ama istek atılabilir | Aynı site / aynı üst alan adı altındaki istemci ve API |
| BFF deseni | Jeton hiç tarayıcıya gitmez; tarayıcıda yalnızca oturum çerezi, gerçek jeton BFF'te | CSRF (çerez var) + BFF'in kendisi bir bileşen daha | Bugünün önerilen varsayılanı — 12-12'de pratiğini yaptın |
| Yalnızca bellek | JS değişkeninde tutulur, hiçbir kalıcı depoya yazılmaz | XSS hâlâ okuyabilir (çalışan betik aynı bellekte); sayfa yenilenince kaybolur | Kısa ömürlü erişim jetonu + sessiz yenileme ile birlikte |
Neden BFF öne çıktı? Çünkü diğer iki seçenek riski istemciye bırakır ve
istemci saldırganın makinesindedir. BFF deseninde tarayıcı hiçbir zaman erişim
jetonunu görmez: httpOnly, Secure, SameSite
bir oturum çerezi vardır, jetonu ve yenilemeyi BFF saklar ve aşağı akış çağrılarına
kendisi ekler. XSS olduğunda saldırgan yine kullanıcı adına istek atabilir
(bu kaçınılmazdır), ama jetonu dışarı çıkaramaz — yani saldırı, kullanıcının
tarayıcısı açık olduğu süreyle sınırlı kalır. Bedeli CSRF'dir ve 4. dersin
araçlarıyla karşılanır.
"Bellekte tut + sessiz yenile" deseni yaygın bir ara çözümdür: erişim
jetonu yalnızca bellekte durur, sayfa yenilendiğinde httpOnly yenileme
çerezi ile arka planda yeni bir erişim jetonu alınır. Kullanıcı yeniden giriş
yapmaz, kalıcı depoda jeton bulunmaz. Karmaşıklığı, birden çok sekmenin aynı anda
yenileme denemesidir — 12-12'deki uçuşta tekilleştirme fikri burada
istemci tarafında uygulanır: aynı anda gelen 401'ler tek bir yenileme çağrısına
abone olur, yoksa yenileme jetonu dönüşümü kendi kendini iptal eder.
Son bir boyut hatırlatması: JWT çereze konursa 4 KB çerez sınırı ve her isteğe binen bayt maliyeti devreye girer. İddia şişmesi (jetona bütün yetkileri doldurmak) hem bu sınırı zorlar hem de yetkinin bayatlamasına yol açar. Kural: jetona kimlik ve kaba yetki bilgisi konur, ince kararlar isteğin anında kaynaktan verilir.
09JWT ne zaman kullanılmamalı
Bu bölüm, jetonu bilmek kadar değerlidir. Tek alan adlı, tek arka uçlu klasik bir web uygulamasında JWT kullanmak neredeyse her zaman yanlış karardır. Sunucu tarafı oturum daha küçük, anında iptal edilebilir, saklanma yeri tartışması yoktur ve kütüphane desteği olgundur. JWT'yi haklı çıkaran gerçek gerekçeler şunlardır:
- Jetonu üreten ile doğrulayan farklı taraflar (kimlik sağlayıcı + çok sayıda API)
- Servisten servise çağrılar ve makineden makineye kimlik (6. dersteki client credentials)
- Mobil ve masaüstü istemciler (çerez mekanizması doğal değil)
- Farklı alan adları arasında federasyon / çoklu oturum açma
Bu gerekçelerden hiçbiri yoksa, "modern" olduğu için JWT seçen ekip, ilk "kullanıcıyı anında çıkart" talebinde iptal problemiyle tanışır. Mülakatta "JWT'yi ne zaman kullanmazdınız?" sorusu tam olarak bunu ölçer.
10Mini alıştırma — jetonu üret, çöz, kır, sertleştir
Yaklaşık 20 dakika · Node + jsonwebtoken (ya da .NET tarafında eşdeğeri)
- Çöz. Bir jeton üret ve üç parçayı elle ayır; başlık ile yükü
Buffer.from(parca, "base64url").toString()ile çöz ve ekrana yaz. "İmzalı = gizli" olmadığını kendi gözünle gör; yüke asla ne koymayacağını bir cümleyle not et. alg: nonedene. Başlığı{"alg":"none"}yapıp imza kısmını boş bırak veverifyçağır. Kütüphanenin reddettiğini gör; sonraalgorithmsparametresini kaldırıp ne olduğunu gözle. Aradaki farkı yaz.- Süreyi ve toleransı sına.
expiresIn: "5s"ile jeton üret, 6 saniye sonra doğrula — hatayı gör. ArdındanclockTolerance: 60ekleyip aynı jetonun geçerli sayıldığını gör. .NET tarafında varsayılanClockSkew'in 5 dakika olduğunu hatırla ve bunun neden bir sürpriz kaynağı olduğunu not et. audkontrolünü kanıtla.audience: "api-a"ile jeton üret,audience: "api-b"bekleyen bir doğrulamaya ver — reddi gör. Sonraaudienceparametresini kaldır ve jetonun kabul edildiğini gör. Bu tek satırın hangi saldırıyı açtığını yaz.- Sırrı kır.
"secret"gibi zayıf bir sırla imzalanmış bir jeton üret ve küçük bir sözlük döngüsüyle (100-200 aday) sırrı bul. Süreyi ölç. Sonracrypto.randomBytes(32)ile üretilmiş bir sırla tekrar dene ve aynı döngünün neden anlamsız olduğunu açıkla. - İptali kur. Kullanıcı kaydına bir
tokenVersionalanı ekle, jetonatviddiası koy ve doğrulamada karşılaştır. "Parola değiştir" ucunda sayacı artır; elindeki eski jetonun anında geçersizleştiğini doğrula. Bunun "durumsuzluk"tan ne kadar taviz verdiğini bir cümleyle yaz.
11Kendini sına
JWT'nin üç parçası nedir; "imzalı" ile "şifreli" farkı nedir? Jetona ne konmaz?
Üç parça: başlık (alg, typ,
kid), yük (iddialar) ve imza; noktayla ayrılır ve ilk iki
parça base64url ile kodlanmıştır — şifrelenmemiştir. Jetonu eline geçiren
herkes yükü tek satırda okur. İmza gizlilik değil bütünlük ve kimlik sağlar:
içerik okunabilir ama değiştirilemez. Standartta bu imzalı biçim JWS'tir;
gerçekten şifreli olan biçim JWE'dir ve nadiren kullanılır, çünkü hassas
veriyi jetona hiç koymamak daha basittir. Dolayısıyla jetona parola, kimlik
numarası, sağlık verisi gibi hiçbir hassas bilgi konmaz; jeton loglara da yazılmaz
(authorization başlığı redaksiyon listesindedir). Standart iddialar:
iss, sub, aud, exp,
nbf, iat, jti.
HS256 ile RS256 arasında nasıl seçim yaparsın? alg: none ve algoritma karıştırma saldırıları nasıl çalışır, tek satırlık savunma nedir?
Kural: doğrulayan taraf sayısı birden fazlaysa asimetrik.
HS256'da sır hem imzalar hem doğrular; onu beş servise dağıtmak beşine de jeton
üretme yetkisi vermektir — en az yetki ihlali. RS256/ES256'da özel anahtar
imzalar, açık anahtar (JWKS ile) yayınlanır ve yalnızca doğrular.
alg: none: standart imzasız jetonu tanımlar; başlığı
none yapıp imzayı silen jetonu erken kütüphaneler geçerli sayıyordu —
kök hata, jetonu gönderenin nasıl doğrulanacağını söylemesine izin verilmesidir.
Algoritma karıştırma: sunucu RS256 bekler ve elinde açık anahtar vardır;
saldırgan başlığı HS256 yapıp jetonu o herkese açık anahtarı HMAC sırrı olarak
kullanarak imzalar, kütüphane anahtarı simetrik sır sanıp doğrular.
Savunma: algoritmayı sunucu dayatır —
algorithms: ["RS256"] / ValidAlgorithms. Ayrıca
kid asla dosya yolu ya da sorguya doğrudan verilmez, beyaz listeye
eşlenir; ve decode ile verify karıştırılmaz —
decode imzayı kontrol etmez.
Doğrulama kontrol listesinde neler var? aud kontrolü atlanırsa ne olur, saat kaymasında hangi varsayılan tuzağı vardır?
Liste: (1) imza — doğru anahtar, sunucunun dayattığı
algoritma; (2) exp/nbf — saat kayması toleransıyla;
(3) iss — beklenen veren; (4) aud;
(5) typ/jeton türü — erişim, kimlik ve yenileme jetonları
birbirinin yerine kullanılmaz; (6) yetki — rol/kapsam kontrolü ayrı bir
adımdır, jetonun geçerli olması onu yetkili yapmaz ve nesne düzeyi (IDOR) kontrolü
yine ayrıca gerekir. aud atlanırsa başka bir API için verilmiş
geçerli bir jeton seninkinde de çalışır: o API'ye jeton alabilen herkes senin
sisteminde kullanıcı olur (jeton karıştırma/yeniden kullanım). Bu, en sık atlanan
kontroldür. Saat kayması: dağıtık sistemlerde küçük bir tolerans gerekir
(30 sn tipik), ama .NET'te ClockSkew varsayılanı 5 dakikadır —
"süresi dolmuş jeton hâlâ çalışıyor" şaşkınlığının klasik sebebi budur, açıkça
kısaltılır.
JWT'nin iptal problemi nedir, dört çözüm kalıbı hangileridir? Yenileme jetonu dönüşümünde yeniden kullanım tespiti ne yapar?
Problem: jeton kendi kendini doğruladığı için verildikten
sonra geri alınamaz — çıkış, hesap askıya alma, rol düşürme, parola değişimi
exp gelene kadar etkisizdir. Dört kalıp: (1) kısa ömür +
yenileme — erişim 5-15 dk, yenileme sunucuda kayıtlı; iptal anında değil, en fazla
bir jeton ömrü gecikir; (2) kara liste — iptal edilen jti'ler
Redis'te, her istekte bakılır (durumsuzluk biter ama depo küçüktür); (3) sürüm
iddiası — jetondaki tv ile kullanıcı kaydındaki sayaç karşılaştırılır,
parola değişiminde sayaç artırılır ve tüm oturumlar anında düşer;
(4) introspection — kimlik sağlayıcıya sorulur, önbellekle yumuşatılır.
Kıdemli sonuç: tam durumsuz kimlik pratikte nadiren kabul edilebilir; dengeli bileşim
kısa ömürlü erişim + kayıtlı yenileme + kritik olaylarda sürüm iddiasıdır.
Dönüşüm ve yeniden kullanım tespiti: her yenilemede eski yenileme jetonu
geçersizleşir; geçersiz bir jeton tekrar sunulursa bu çalınmış bir kopyanın işaretidir
ve doğru davranış tüm jeton ailesini iptal edip kullanıcıyı yeniden giriş yapmaya
zorlamaktır — saldırgan jetonu kullandığı anda olay görünür olur. Yenileme
jetonunun ayrıca mutlak ömrü olur ve istemciye bağlanır.
12Sınav köşesi
Yazılıda nasıl sorulur
(1) JWT nedir, hangi parçalardan oluşur? (2) Payload şifreli midir?
(3) Standart claim'leri (iss, sub, aud, exp, nbf, iat, jti) açıklayın.
(4) HS256 ile RS256 arasındaki fark nedir, hangisi ne zaman kullanılır?
(5) alg: none saldırısı nedir? (6) Algorithm confusion saldırısı
nasıl çalışır? (7) JWT doğrulamasında hangi kontroller yapılmalıdır?
(8) Audience kontrolü neden gereklidir? (9) JWT nasıl iptal edilir?
(10) Access token ve refresh token farkı nedir? (11) Refresh token rotation ve
reuse detection nedir? (12) JWT tarayıcıda nerede saklanmalıdır, seçenekleri
karşılaştırın. (13) JWT ne zaman kullanılmamalıdır?
Sözlüde nasıl anlatılır — 2 dakikalık taslak
Düzen: (1) Tanım — "JWT, imzalı üç parçalı bir jetondur: başlık, yük, imza.
Yük base64url ile kodlanmıştır, şifrelenmemiştir — okunabilir; o yüzden
içine hassas veri koymam ve loglamam." (2) Anahtar — "Doğrulayan taraf birden
fazlaysa asimetrik kullanırım; HS256'da sırrı dağıtmak, o servislere jeton üretme
yetkisi vermektir." (3) Doğrulama — "Doğrulama bir kontrol listesidir: imza,
sunucunun dayattığı algoritma beyaz listesi, exp/nbf ve saat kayması, iss ve
aud. Algoritmayı jetondan okuyan kod alg:none ve algoritma
karıştırmaya açıktır; aud'u atlayan kod başka bir API'nin jetonunu
kabul eder." (4) İptal — "JWT'nin gerçek bedeli iptaldir: çıkış yaptırmak,
hesabı askıya almak exp gelene kadar işlemez. Bunu kısa ömürlü erişim jetonu +
sunucuda kayıtlı yenileme jetonu + kritik olaylarda sürüm iddiasıyla çözerim;
yenilemede dönüşüm ve yeniden kullanım tespiti uygularım — çalıntı jeton
kullanıldığı anda tüm aileyi iptal ederim." (5) Kıdem vuruşu — "Saklama sorusunda
tek doğru yok, risk yer değiştirir: localStorage'da XSS jetonu dışarı çıkarır,
httpOnly çerezde CSRF gelir, BFF deseninde jeton tarayıcıya hiç inmez ve
bugünün varsayılanı odur. Ve tersini de söylerim: tek alan adlı klasik bir web
uygulamasında JWT kullanmam — sunucu tarafı oturum daha basit ve anında iptal
edilebilir; JWT'yi çok doğrulayıcı, mobil ya da federasyon gibi gerçek bir gerekçe
varsa seçerim."
