Backend Uygulamalarında Authentication: JWT Nasıl Çalışır?
JWT'nin kodlama, imza ve doğrulama katmanlarını ayıralım; issuer, audience, algoritma sınırı, refresh token ve kaynak yetkilendirmesini birlikte tasarlayalım.
JWT ile authentication anlatılırken çoğu örnek “token üret, header'a ekle, decode et” aşamasında kalır. Oysa decode işlemi güven tesis etmez. Bir backend'in karar vermesi gereken şey yalnızca token'ın içinde ne yazdığı değil, bu bilginin kimden geldiği ve bu API için geçerli olup olmadığıdır.
Ayrıca authentication ve authorization farklı sorulardır. Authentication kimliği, authorization ise o kimliğin belirli bir işlemi yapma yetkisini değerlendirir.
JWT'nin içinde ne bulunur?
Yaygın imzalı JWT biçimi üç bölümden oluşur: header, payload ve signature. İlk iki bölüm Base64URL ile kodlanır. Kodlama şifreleme değildir; token'ı alan kişi payload'ı okuyabilir.
Bu nedenle payload içine parola, özel anahtar veya gereksiz kişisel veri koymayın. İmza, içeriğin değiştirilip değiştirilmediğini ve uygun anahtarla üretildiğini doğrulamaya yardımcı olur. Şifrelenmiş token biçimleri farklı bir katmandır.
Örnek bir claim set'i:
{
"iss": "https://identity.example.com/",
"aud": "task-api",
"sub": "user_42",
"exp": 1786536300,
"scope": "tasks:read"
}
Bu değerler örnektir ve gerçek token değildir. iss üreticiyi, aud hedef alıcıyı, sub özneyi, exp son geçerlilik zamanını ifade eder. Zaman claim'lerinde NumericDate saniye temellidir; JavaScript'in milisaniye timestamp'iyle karıştırılmamalıdır. Temel format RFC 7519 içinde tanımlanır.
Decode etmek neden yeterli değil?
Bir saldırgan farklı payload oluşturup kodlayabilir. JSON'un çözümlenebilmesi veya role: admin alanı içermesi yetki vermez. İmza, izin verilen algoritma, doğru anahtar ve beklenen claim değerleri birlikte doğrulanmalıdır.
Algoritma seçimini denetimsiz şekilde token header'ına bırakmayın. Beklenen issuer ve audience uygulama yapılandırmasından gelmelidir. Farklı amaçlarla üretilen token'ların birbirinin yerine kabul edilmesi de ayrı bir risktir. Bu sınıflandırmalar JWT Best Current Practices belgesinde ele alınır.
Örneğin frontend'e kullanıcı bilgisini taşımak için üretilen bir ID token'ı, API'nin access token'ı gibi kabul etmek doğru değildir.
Node.js tarafında doğrulama örneği
Aşağıdaki ESM parçası jose paketiyle imzalı access token doğrulamasını gösterir. Örnek issuer ve JWKS adresleri gerçek kimlik sağlayıcınızla değiştirilmelidir; internetten keyfi bir adres seçilmez.
import { createRemoteJWKSet, jwtVerify } from "jose";
const issuer = "https://identity.example.com/";
const audience = "task-api";
const keys = createRemoteJWKSet(
new URL("https://identity.example.com/.well-known/jwks.json")
);
export async function verifyAccessToken(token) {
const { payload } = await jwtVerify(token, keys, {
issuer,
audience,
algorithms: ["RS256"],
requiredClaims: ["exp", "sub"],
clockTolerance: 5,
});
if (typeof payload.sub !== "string" || payload.sub.length === 0) {
throw new Error("Invalid subject");
}
return payload;
}
RS256 burada sağlayıcının bu algoritmayı kullandığı varsayımıdır; kendi token sözleşmenizi izleyin. Clock tolerance küçük saat farklarını karşılar, sınırsız geçerlilik yaratmak için kullanılmaz. jwtVerify doğrulama API'sini, remote JWKS ise anahtar çözümlemeyi açıklar.
Bu fonksiyon HTTP middleware'in tamamı değildir. Eksik veya hatalı Bearer biçimi, token uzunluk sınırı ve hata yanıtları ayrıca ele alınmalıdır. Ağ veya kimlik sağlayıcı kesintisini de gözlemleyin; her hatayı sessizce “yanlış parola” gibi sunmayın.
İmza doğruysa her işlem serbest mi?
Hayır. Doğrulanmış token yalnızca güvenilen claim'leri sağlar. Kullanıcının /tasks/42 kaynağını okumaya yetkili olup olmadığı veri ve iş kurallarıyla değerlendirilir.
Scope kontrolü, tenant sınırı ve sahiplik denetimi ayrı olabilir. Kullanıcı rolü değiştiğinde daha önce üretilen token eski rolü taşımaya devam edebilir. Bu nedenle kısa token ömrü, kritik işlemlerde güncel yetki kontrolü veya sunucu tarafı iptal stratejisi gerekebilir.
“JWT kullanıyoruz, sunucuda hiç state tutmayız” iddiası pratikte refresh token, iptal ve hesap güvenliği ihtiyaçlarıyla sık karşılaşır.
Access ve refresh token yaşam döngüsü
Access token kısa süreli API erişimi için, refresh token ise yeni erişim token'ı alma süreci için kullanılabilir. Refresh token'ı her API'ye göndermek gerekmez. Yenileme endpoint'i için saklama, rotation, tekrar kullanım tespiti ve oturum sonlandırma politikası tasarlanmalıdır.
Logout sırasında tarayıcıdaki token'ı silmek, çalınmış başka bir kopyayı kendiliğinden geçersiz yapmaz. Süre sonu, denylist veya kimlik sağlayıcının oturum/iptal özellikleri gereksinime göre seçilir.
Tarayıcıda saklama ve güvenli taşıma
JavaScript'in erişebildiği saklama alanları XSS etkisi altında token sızıntısı riski taşır. HttpOnly cookie JavaScript erişimini sınırlar, ancak cookie'nin otomatik gönderilmesi CSRF tasarımını gerekli kılabilir. SameSite, Secure, origin kontrolleri ve gerektiğinde CSRF token birlikte değerlendirilmelidir.
TLS taşıma sırasında gereklidir; JWT imzası ağ şifrelemesinin yerini almaz. Token'ları URL query parametresine veya loglara yazmak da kopyaların istemeden yayılmasına yol açabilir.
JWT bir güvenlik mimarisinin parçasıdır. Güvenilir kimlik sağlayıcı, doğrulama sözleşmesi, kaynak yetkisi ve iptal davranışı bir araya geldiğinde anlamlı hale gelir.
Related Posts
Node.js ve Express ile İlk REST API’ni Geliştirmek
Node.js ve Express ile bir görev yönetimi API’si geliştirelim: endpoint tasarımı, veri doğrulama, HTTP durum kodları ve merkezi hata yönetimi.
Node.js Uygulamasını Production’a Hazırlamak: Logging, Error Handling ve Security
Çalışan bir Node.js API'sini işletilebilir hale getirelim: yapılandırma doğrulama, hata sınırları, güvenli loglama, kaynak limitleri ve kontrollü kapanma.
Node.js Uygulamalarında Redis Neden Kullanılır?
Cache-aside örneğinden TTL, invalidation, stampede ve eviction kararlarına; Redis'in performans kazancı ile tutarlılık maliyetini birlikte değerlendirelim.