aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Web Geliştirme

JWT Nedir? Token ile Kimlik Doğrulama Mantığı

Bir API yazarken eninde sonunda şu soruyla karşılaşırsın: kullanıcı giriş yaptıktan sonra, sonraki her istekte onu nasıl tanıyacağım? İşte jwt nedir sorusunun cevabı tam burada devreye giriyor. JWT (JSON Web Token), sunucunun ürettiği, imzaladığı ve istemciye verdiği kendi kendine yeten bir kimlik kartı gibidir. İstemci bu kartı her istekte geri gönderir, sunucu da imzasına bakıp "evet bu gerçekten benim verdiğim token" diyebilir; üstelik veritabanına dönüp sorgu yapmadan.

JWT nedir ve neden kullanılır?

Klasik oturum yönetiminde sunucu, her giriş yapan kullanıcı için sunucu tarafında bir session kaydı tutar ve istemciye bir session id verir. Bu yaklaşım çalışır ama sunucunun durumu (state) hatırlamasını gerektirir. Birden fazla sunucun varsa, hepsinin aynı oturum deposunu paylaşması gerekir.

JWT bunu tersine çevirir. Token'ın içinde kullanıcıyla ilgili bilgiler (kim olduğu, rolü, son kullanma tarihi) zaten yazılıdır ve sunucunun gizli anahtarıyla imzalanmıştır. Sunucu hiçbir şey hatırlamak zorunda değildir; gelen token'ın imzasını doğrulaması yeterlidir. Bu yüzden JWT'ye stateless (durumsuz) kimlik doğrulama denir. Mikroservislerde, mobil uygulamalarda ve API'lerde bu kadar yaygın olmasının sebebi de budur.

Token'ın üç parçası

Bir JWT, nokta ile ayrılmış üç parçadan oluşur: header.payload.signature. Her parça Base64Url ile kodlanmıştır (şifrelenmiş değil, sadece kodlanmıştır — bu önemli bir ayrım).

  • Header (başlık): Token'ın tipini ve kullanılan imza algoritmasını söyler. Örnek: {"alg":"HS256","typ":"JWT"}.
  • Payload (yük): "Claim" denen iddiaları taşır. Örneğin kullanıcı id'si (sub), son kullanma zamanı (exp), oluşturulma zamanı (iat) ve kendi eklediğin alanlar (rol gibi).
  • Signature (imza): Header ve payload'ın gizli anahtarla imzalanmış halidir. Token'ın değiştirilmediğini garanti eden parça budur.

Gerçek bir token şuna benzer:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3MTk1MDAwMDB9
.s5_3kF9vQk2...imza

Çok önemli bir nokta: payload şifreli değildir. Base64Url herkes tarafından çözülüp okunabilir. Bu yüzden token'ın içine şifre, kredi kartı numarası gibi gizli veriler asla koyma. Token sadece "kimliği" taşır, sırları değil.

İmzalama nasıl çalışır?

İmza, JWT'nin tüm güvenlik mantığının kalbidir. HS256 (HMAC + SHA-256) algoritmasında imza şöyle hesaplanır:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  gizliAnahtar
)

Sunucu token'ı doğrularken aynı işlemi tekrar yapar: gelen header ve payload'ı kendi gizli anahtarıyla yeniden imzalar ve sonucu token'daki imzayla karşılaştırır. Eğer biri payload'daki rolü user'dan admin'e çevirmeye kalkarsa imza tutmaz, çünkü saldırganın gizli anahtarı yoktur. İşte token'ın "kurcalanamaz" olmasının sebebi bu.

İki tür imza yaklaşımı vardır:

  • HS256 (simetrik): Tek bir gizli anahtar hem imzalar hem doğrular. Basit, hızlı; ama doğrulayan herkes aynı zamanda token üretebilir.
  • RS256 (asimetrik): Özel anahtarla imzalar, açık anahtarla doğrulanır. Birden fazla servis token'ı doğrulamak zorundaysa ama üretmemeli ise idealdir.

Pratikte: token üretmek ve doğrulamak

Node.js'te jsonwebtoken kütüphanesiyle akış çok sade görünür:

const jwt = require('jsonwebtoken');

// Giriş başarılı olunca token üret
const token = jwt.sign(
  { sub: user.id, role: user.role },
  process.env.JWT_SECRET,
  { expiresIn: '15m' }
);

// Sonraki isteklerde doğrula
try {
  const payload = jwt.verify(token, process.env.JWT_SECRET);
  // payload.sub ile kullanıcıyı tanı
} catch (err) {
  // imza geçersiz ya da süresi dolmuş
}

İstemci bu token'ı genelde Authorization: Bearer <token> başlığıyla gönderir. Sunucudaki bir middleware her istekte bu başlığı okur, doğrular ve kullanıcıyı isteğe iliştirir.

Refresh token mantığı

Burada bir gerilim var: token'ın kısa ömürlü olmasını istersin (çalınırsa zarar az olsun), ama kullanıcıyı her 15 dakikada bir tekrar giriş yaptırmak da kötü bir deneyim. Çözüm iki token kullanmaktır:

  • Access token: Kısa ömürlü (örneğin 15 dakika). Her API isteğinde gönderilir.
  • Refresh token: Uzun ömürlü (örneğin 7 gün). Sadece yeni bir access token almak için kullanılır.

Access token süresi dolduğunda istemci, refresh token'ı sunucuya gönderir ve karşılığında taze bir access token alır — kullanıcı hiçbir şey fark etmez. Önemli güvenlik detayları:

  • Refresh token'ı sunucu tarafında saklamak (ya da bir kara liste tutmak) gerekir ki "çıkış yap" işlemi gerçekten token'ı iptal edebilsin. Saf access token stateless olduğu için süresi dolana kadar geçerli kalır.
  • Refresh token'ı tarayıcıda HttpOnly bir cookie'de tutmak, JavaScript'in ona erişip XSS ile çalmasını engeller.
  • Her kullanımda yeni bir refresh token verip eskisini geçersiz kılmak (rotation) çalınma riskini ciddi şekilde azaltır.

Sık yapılan hatalar

  • Gizli verileri payload'a koymak: Payload herkese açıktır, unutma.
  • Süre (exp) koymamak: Süresiz token, çalındığında sonsuza kadar geçerlidir.
  • alg: none kabul etmek: Kütüphaneni hangi algoritmaları kabul edeceğini açıkça belirtecek şekilde yapılandır.
  • Gizli anahtarı koda gömmek: Anahtar ortam değişkeninde (.env) durmalı, repoda değil.

Sık Sorulan Sorular

JWT şifreli midir?

Hayır. JWT varsayılan olarak imzalıdır, şifreli değildir. Yani içeriği okunabilir ama değiştirilemez. İçeriği de gizlemek istiyorsan JWE (JSON Web Encryption) ayrı bir standarttır; ama çoğu durumda gizli veriyi token'a hiç koymamak daha doğrudur.

Token'ı nerede saklamalıyım?

Tek bir mükemmel cevap yok. localStorage kolaydır ama XSS'e açıktır. HttpOnly cookie XSS'e karşı korumalıdır ama CSRF önlemi gerektirir. Mobil uygulamalarda güvenli depolama (Keychain/Keystore) tercih edilir.

Bir JWT'yi tek tek iptal edebilir miyim?

Saf JWT stateless olduğu için doğrudan iptal edilemez; süresi dolana kadar geçerlidir. İptal gerekiyorsa kısa ömürlü access token + sunucuda tutulan refresh token (kara liste) yaklaşımını kullanırsın.

Kimlik doğrulamayı doğru kurmak, bir projenin güvenliğinin temelidir. JWT, refresh token akışı veya genel olarak güvenli bir API mimarisi kurmakta yardıma ihtiyacın varsa, benimle iletişime geç — birlikte sağlam bir temel atalım.

Bu kategorideki tüm yazılar →

Devamı için