JWT Nedir ve Güvenle Nasıl Çözülür
JSON Web Token'lar modern web geliştirmenin her yerinde görünür — kimlik doğrulama başlıkları, OAuth akışları, API anahtarları, oturum yönetimi. Bearer belirteci gerektiren herhangi bir API ile çalıştıysanız, zaten bir JWT kullandınız. Ancak çoğu geliştirici onları opak kütleler olarak ele alır ve nadiren içine bakar. Bir JWT'nin yapısını, her bölümün ne anlama geldiğini ve güvenlik hataları yapmadan birini nasıl çözeceğinizi anlamak yaklaşık on beş dakika sürer. Bu kılavuz hepsini kapsar.
Bir JWT'nin Anatomisi
Her JWT, noktalarla ayrılmış üç Base64URL kodlu segmentten oluşan bir dizgidir:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImlzcyI6Imh0dHBzOi8vYXV0aC5leGFtcGxlLmNvbSIsImF1ZCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIiwiZXhwIjoxNzQ3MDAwMDAwLCJpYXQiOjE3NDY5OTY0MDAsInNjb3BlIjoicmVhZDp1c2VycyJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c Format header.payload.signature'dir. Her segment farklı bilgiler kodlar.
Header
İlk segment header'dır. Çözüldüğünde, yukarıdaki örnek şu hale gelir:
{
"alg": "RS256",
"typ": "JWT"
} alg belirteci imzalamak için kullanılan algoritmayı belirtir — RS256, SHA-256 ile RSA anlamına gelir. typ belirteç türünü tanımlar. Bu iki alan minimumdur; bazı belirteçler ayrıca rotasyonda birden fazla anahtar olduğunda doğrulayıcıya hangi açık anahtarın kullanılacağını söylemek için kid (anahtar kimliği) içerir.
Payload
İkinci segment payload'dur — gerçek veri. Çözüldüğünde:
{
"sub": "user_123",
"iss": "https://auth.example.com",
"aud": "https://api.example.com",
"exp": 1747000000,
"iat": 1746996400,
"scope": "read:users"
} Payload talepler içerir: belirtecin temsil ettiği varlık hakkındaki ifadeler. Bazı talepler standartlaştırılmıştır (kayıtlı talepler olarak adlandırılır); diğerleri uygulamaya özgüdür (özel talepler olarak adlandırılır). Payload Base64URL kodludur, şifrelenmemiştir. Belirteç dizgisini alan herkes içindeki her talebi okuyabilir.
İmza
Üçüncü segment imzadır. Kodlanmış header ve payload'u alıp bir nokta ile birleştirerek, ardından alg'de belirtilen gizli anahtar veya özel anahtarla sonucu imzalayarak üretilir:
signature = sign(
base64url(header) + "." + base64url(payload),
secretOrPrivateKey
) İmza, ilgili açık anahtara (veya simetrik algoritmalar için gizli anahtar) sahip herhangi bir tarafa, belirtecin güvenilir bir kaynak tarafından verildiğini ve verildikten sonra ne header'ın ne de payload'un değiştirilmediğini doğrulamasına olanak tanır. Payload'da değişen tek bir karakter imzayı tamamen geçersiz kılar.
Bir JWT Nasıl Çözülür
Çözme, doğrulamadan farklıdır. Çözme, belirteç içindeki verileri okur. Doğrulama, belirtecin orijinal ve süresinin dolmadığını onaylar. Üretim kodunda her zaman doğrulamalısınız; çözme tek başına hata ayıklama için yararlıdır.
Adım 1: Belirteci bölün
JWT dizgisini . karakterinde bölün. Üç segment alacaksınız. Üçten az alırsanız, belirteç hatalı biçimlendirilmiştir.
Adım 2: Header ve payload'u çözün
İlk iki segmentin her birini Base64URL ile çözün. Base64URL standart Base64 gibidir ancak + yerine - ve / yerine _ kullanır, dolgu karakterleri yoktur. Çözüldükten sonra, her segmenti JSON olarak ayrıştırabilirsiniz.
Adım 3: Ayrıştırın ve inceleyin
Talepleri okuyun. Mevcut Unix zaman damgasına karşı exp'i (son kullanma) kontrol edin. Belirtecin uygulamanız için tasarlandığını onaylamak için iss ve aud'ye bakın. İmzayı doğrulamadan herhangi bir talebe güvenmeyin.
Geliştirme sırasında hızlı inceleme için, JWT Decoder'ı kullanın. Tamamen tarayıcınızda çalışır — belirteciniz cihazınızdan asla çıkmaz. Ham baytları görmek istiyorsanız, base64 segmentlerini Base64 kodlayıcı/çözücü ile manuel olarak da çözebilirsiniz. Test betiklerinde imzaları doğrulamak için, HMAC generator kod yazmadan HS256 imzalarını yeniden üretmenize olanak tanır.
Adım 4: Kodda imzayı doğrulayın
Üretimde, her zaman diliniz için yapılmış bir kütüphane kullanarak imzayı doğrulayın. İmza doğrulamasını elle uygulamayın. Popüler seçenekler arasında Node.js için jose veya jsonwebtoken, Python için PyJWT, Go için golang-jwt/jwt ve Java için nimbus-jose-jwt bulunur.
Algoritmayı her zaman açıkça geçirin. Kütüphanenin algoritmayı belirteç header'ından çıkarmasına asla izin vermeyin.
Standart Talepler (Kayıtlı Talepler)
RFC 7519 bir dizi kayıtlı talep adı tanımlar. Bunlar zorunlu değildir, ancak mevcut olduklarında standart semantiği takip etmelidir.
iss — Yayıncı
Belirteci oluşturan ve imzalayan varlık. Genellikle yetkilendirme sunucusunu tanımlayan bir URL (örneğin, https://auth.example.com). Doğrulayıcılar iss'in beklenen bir değerle eşleştiğini kontrol etmeli ve bilinmeyen yayıncılardan gelen belirteçleri reddetmelidir.
sub — Özne
Belirtecin temsil ettiği temel — tipik olarak bir kullanıcı kimliği, hizmet hesabı adı veya cihaz tanımlayıcısı. Değer, yayıncının bağlamında benzersiz olmalıdır. Uygulamanız, isteğin hangi kullanıcıya ait olduğunu belirlemek için sub'u kullanır.
aud — Hedef Kitle
Belirtecin amaçlanan alıcı(lar)ı. API'nizin tanımlayıcısı https://api.example.com ise, diğer hizmetler için verilen belirteçler reddedilmelidir. aud'yi doğrulamamak, saldırganların bir hizmetten elde edilen bir belirteci farklı bir hizmette yeniden kullanmasına olanak tanır.
exp — Son Kullanma Zamanı
Bir Unix zaman damgası, bundan sonra belirteç kabul edilmemelidir. Her zaman exp'i doğrulayın. Son kullanma süresi olmayan bir belirteç etkin olarak sonsuza kadar yaşar — çalınırsa, saldırgan süresiz erişime sahip olur.
iat — Verildiği Zaman
Belirtecin oluşturulduğu Unix zaman damgası. Teknik olarak süresi dolmamış ancak şüpheli derecede eski belirteçleri algılamak için kullanışlıdır. exp'den bağımsız olarak maksimum belirteç yaşını zorunlu kılmak için iat'i kullanabilirsiniz.
nbf — Önce Değil
Bundan önce belirtecin kabul edilmemesi gereken Unix zaman damgası. exp'den daha az yaygındır, ancak önceden belirteçler verirken kullanışlıdır — örneğin, belirli bir zamana kadar başlamaması gereken zamanlanmış bir görev.
jti — JWT Kimliği
Belirteç için benzersiz bir tanımlayıcı. Yayıncıların kullanılmış jti değerlerini depolayarak ve yinelenen kimliklerle belirteçleri reddederek belirteç yeniden oynatma saldırılarını önlemesine olanak tanır. Parola sıfırlama bağlantıları gibi tek seferlik kullanım belirteçlerine ihtiyacınız olduğunda gereklidir.
Güvenlik Tuzakları
JWT uygulamalarının ince güvenlik açıkları geçmişi vardır. JWT'leri kabul eden kodları göndermeden önce anlaşılması en önemli olanlar bunlardır.
"alg: none" Saldırısı
Standardın ilk günlerinden bazı JWT kütüphaneleri, header'ında "alg": "none" belirten bir belirteci kabul ederdi. Bir saldırgan herhangi bir geçerli belirteci alıp, algoritmayı none ile değiştirip, imzayı sıyırabilirdi ve kütüphane bunu tamamen geçerli olarak kabul ederdi — imza gerekmez.
Düzeltme: doğrulama fonksiyonunuzu çağırırken her zaman beklenen algoritmayı açıkça belirtin. alg: none iddia eden herhangi bir belirteci geçersiz olarak değerlendirin. Çoğu modern kütüphane bunu ele almıştır, ancak üretime geçmeden önce kütüphanenizin varsayılanlarını onaylamaya değer.
Algoritma Karıştırma (RS256'dan HS256'ya Düşürme)
Her iki algoritmayı destekleyen bazı kütüphaneler, doğrulamayı nasıl yapacağına karar vermek için belirteç header'ındaki alg alanını kullanırdı. Bir saldırgan algoritmayı HS256'ya değiştirip, ardından sunucunun açık anahtarını HMAC sırrı olarak kullanarak belirteci imzalayabilirdi. Sunucu, HS256 gördüğünde, açık anahtara karşı doğrular ve sahte belirteci kabul ederdi.
Düzeltme aynıdır: doğrulama kodunuzda algoritmayı kilitleyin. Belirteç header'ının hangi algoritmanın doğrulama için kullanılacağını etkilemesine asla izin vermeyin.
Süresi Dolmuş Belirteçleri Kabul Etme
exp'i doğrulamamak yaygın bir gözden kaçırmadır — bazen geliştiriciler sınırsız büyüyen bir tolerans dönemi eklediğinde veya doğrulama kod yolu bir kod dalında atlandığında ortaya çıkar. Süresi dolmuş bir belirteci eksik bir belirteçle aynı şekilde değerlendirin: 401 ile reddedin ve istemcinin yeniden kimlik doğrulaması yapmasını veya bir refresh belirteci kullanmasını gerektirin.
Payload'ta Hassas Veri
Payload Base64URL kodludur, şifrelenmemiştir. Belirteci yakalayan herkes onu çözebilir. Payload'a parolaları, kredi kartı numaralarını, sosyal güvenlik numaralarını veya diğer hassas verileri koymayın. Hassas talepleri güvenle iletmeniz gerekirse, payload'u şifreleyen bir JWE (JSON Web Encryption) belirteci kullanın. JWS ile imzalanan JWT'ler (yaygın durum) yalnızca orijinalliği garanti eder, gizliliği değil.
Eksik Hedef Kitle Doğrulaması
aud doğrulamasını atlamak, A Hizmeti için verilen bir belirtecin B Hizmetinde tekrar oynatılabileceği anlamına gelir — her iki hizmet de aynı imzalama anahtarını paylaştığı veya aynı yayıncıya güvendiği sürece. Çoklu hizmet mimarilerinde, her zaman belirtecin hedef kitlesinin hizmetinizin tanımlayıcısıyla eşleştiğini doğrulayın.
2026 İçin En İyi Uygulamalar
Çoğu Uygulama İçin RS256'yı Seçin
RS256, imzalamak için bir özel anahtar ve doğrulamak için bir açık anahtar kullanır. Yalnızca yetkilendirme sunucusu özel anahtarı tutar. Herhangi bir hizmet, açık anahtarı kullanarak belirteçleri doğrulayabilir; açık anahtar serbestçe yayınlanabilir (genellikle bir JWKS uç noktası aracılığıyla). Herhangi bir bireysel hizmet tehlikeye atılırsa, saldırganlar belirteçleri doğrulama yeteneği kazanır — ancak yeni belirteçler oluşturma yeteneği değil.
HS256, hem imzalama hem de doğrulama için tek bir paylaşılan sır kullanır. Belirteçleri doğrulayabilen herhangi bir hizmet, bunları oluşturabilir. Bir mikroservis kurulumunda, sırrı birçok hizmette paylaşmak bir ihlalin patlama yarıçapını artırır.
Erişim Belirteçlerini Kısa Ömürlü Tutun
JWT'ler için yerleşik bir iptal mekanizması yoktur — bir kez verildiğinde, bir belirteç süresi dolana kadar geçerlidir (bir engelleme listesi uygulamadığınız sürece, ki bu sunucu tarafı durumu yeniden tanıtır). Kısa son kullanma süreleri (15 dakika ile 1 saat) bir belirteç çalınırsa hasar penceresini sınırlar. Erişim belirteçlerini, localStorage'da değil, güvenli HttpOnly çerezlerinde depolanan uzun ömürlü refresh belirteçleriyle eşleştirin.
Refresh Belirteç Rotasyonunu Kullanın
Bir istemci yeni bir erişim belirteci almak için bir refresh belirteci kullandığında, yeni bir refresh belirteci verin ve eskisini geçersiz kılın. Bu şekilde, çalınmış bir refresh belirteci, meşru istemci orijinali kullanmaya çalıştığı bir sonraki sefer algılanır: sunucu yeniden kullanılmış bir refresh belirteci görür ve tüm oturumu iptal edebilir. Bu desen RFC 6819'da açıklanmıştır ve modern yetkilendirme sunucuları tarafından geniş çapta desteklenir.
Bir JWKS Uç Noktası Yayınlayın
Bir JSON Web Key Set (JWKS) uç noktası (kuralen /.well-known/jwks.json) imzalama açık anahtarlarınızı standart bir formatta yayınlar. Diğer hizmetler JWKS'i alabilir ve anahtarları band dışı verilmeden belirteçleri doğrulayabilir. Bu ayrıca anahtar rotasyonunu basit hale getirir: yeni anahtarı JWKS'e ekleyin, onunla imzalamaya başlayın, ardından tüm mevcut belirteçler süresi dolduktan sonra eski anahtarı kaldırın.
Anahtarları Düzenli Olarak Döndürün
Özel anahtarınız hiç tehlikeye atılmasa bile, anahtarları düzenli olarak döndürmek çalınmış bir anahtarın belirteçleri sahteleştirmek için kullanılabileceği pencereyi sınırlar. JWT header'larınızda imzalama anahtarına başvurmak için kid'i kullanın, böylece doğrulayıcılar rotasyon sırasında mevcut belirteçleri bozmadan JWKS'inizden doğru açık anahtarı seçebilir.
Her Talebi Doğrulayın
Her istekte iss, aud, exp ve nbf'yi kontrol edin. Kurulumunuzda gereksiz görünseler bile bunlardan hiçbirini atlamayın — onları bugün gereksiz gösteren koşullar, bir olay sırasında tam olarak değişen koşullardır.
JWT vs. Oturum Çerezleri
JWT'ler ve sunucu tarafı oturumlar aynı sorunu çözer — durumsuz HTTP'de kimlik doğrulama durumunu sürdürme — ancak farklı ödünler ile.
JWT'ler bağımsızdır. Sunucunun bir isteği doğrulamak için bir veritabanını sorgulaması gerekmez. Bu, onları dağıtık sistemler ve mobil veya üçüncü taraf istemciler tarafından tüketilen API'ler için çekici yapar. Olumsuz yanı, iptal etmenin bir engelleme listesi (sunucu tarafı durumu yeniden tanıtır) veya tehlikeye atılmış bir belirtecin kalan ömrünü tolere etmeyi gerektirmesidir.
Oturum çerezleri sunucu tarafından doğrulanır. Sunucu oturum durumunu saklar ve oturumu silerek erişimi anında iptal edebilir. HttpOnly ve Secure bayraklarına sahip çerezler JavaScript erişiminden ve ağ izinden korunur. Olumsuz yanı, her isteğin bir veritabanı aramasını gerektirmesi ve ölçekte bir darboğaz olabilmesidir.
Sunucu tarafından işlenen sayfalar ve tek bir arka uçla geleneksel web uygulamaları için, oturum çerezleri sağlam ve daha basit bir seçim olmaya devam ediyor. Birden fazla istemci, mikroservis mimarileri ve mobil uygulamalar tarafından tüketilen API'ler için, kısa son kullanma ve refresh belirteç rotasyonlu JWT'ler daha pratik seçenektir.
Belirtecinizi Çözün
Bir JWT'yi incelemenin en hızlı yolu onu JWT Decoder'a yapıştırmaktır. Belirteci böler, header ve payload'u çözer ve talepleri okunabilir bir formatta işler — hepsi belirtecinizi hiçbir yere göndermeden. Ham Base64URL dizgilerini manuel olarak kodlamanız veya çözmeniz gerekirse, Base64 kodlayıcı/çözücü hem standart hem de URL güvenli varyantları ele alır. Test betiklerinde HMAC imzalarını doğrulamak için, HMAC generator bir HS256 imzasını yeniden üretmenize ve belirtecinizin içerdiğiyle karşılaştırmanıza olanak tanır.
Tam şartname için, RFC 7519 (JWT) ve jwt.io'daki etkileşimli örneklere bakın.