Bir JWT'nin anatomisi
JWT (JSON Web Token), RFC 7519 ile tanımlanan, taraflar arasında 'iddia' (claim) taşımaya yarayan kompakt bir biçimdir. En yaygın hâli imzalı JWT'dir: RFC 7515'teki JWS kompakt serileştirmesiyle header.payload.signature düzeninde, noktayla ayrılmış üç parça. Parçalar Base64URL ile kodlanır; bu kodlama standart Base64'teki + ve / yerine - ve _ kullanır, sondaki = dolgusunu atar. Header çoğunlukla {"alg" ile başladığından token'ların büyük kısmı eyJ harfleriyle başlar.
Header, imza algoritmasını (alg; örneğin HS256, RS256, ES256), tipi (typ) ve bazen hangi anahtarın kullanıldığını (kid) söyler. Payload ise iddiaları taşır. RFC 7519 yedi kayıtlı iddia adı tanımlar: iss (yayınlayan), sub (konu, çoğunlukla kullanıcı kimliği), aud (hedef kitle), exp (son geçerlilik), nbf (bundan önce geçersiz), iat (oluşturulma) ve jti (token kimliği). email, role veya scope gibi alanlar uygulamaya özgüdür.
Önemli ayrım şudur: JWS'de iddialar imzalanır ama şifrelenmez. Token'ı ele geçiren herkes payload'ı okuyabilir; imza yalnızca içeriğin değiştirilmediğini kanıtlamaya yarar. İçeriği gizlemek gereken durumlar için JWE (şifreli JWT) vardır ve kompakt biçimi beş parçadan oluşur. JWT Decoder şifreli token'ları çözemez; beş parçalı bir JWE yapıştırıldığında ikinci parça JSON olmadığı için hata gösterir.
Zaman alanlarını doğru okumak
exp, nbf ve iat alanları RFC 7519'daki NumericDate türündedir: 1970-01-01T00:00:00Z anından itibaren geçen saniye sayısı, artık saniyeler hesaba katılmadan. JWT Decoder bu sayıları tarayıcınızın saat dilimine göre yerel tarihe çevirir. En sık karşılaşılan hata, alanın saniye yerine milisaniye ile yazılmasıdır. 13 haneli bir değer saniye sanıldığında tarih on binli yıllara düşer; bu, token'ı üreten tarafta bir hata olduğunu gösterir.
Standarda göre exp zamanında veya sonrasında token işleme alınmamalı, nbf zamanından önce de kabul edilmemelidir. RFC 7519, saat farklarını tolere etmek için genellikle birkaç dakikayı aşmayan küçük bir pay (leeway) tanınabileceğini söyler. Bu nedenle sunucu ile istemci arasındaki birkaç dakikalık saat farkı, süresi yeni dolmuş bir token'ın bir yerde kabul edilip başka yerde reddedilmesini açıklayabilir.
Araç exp değerini cihazınızın saatiyle karşılaştırır ve üstte 'süresi dolmuş' ya da 'süresi geçerli' yazar. Bilgisayarınızın saati yanlışsa bu sonuç da yanlış olur. nbf alanının tarihi gösterilir, ancak henüz geçerlilik başlamamış bir token için ayrı bir uyarı üretilmez. 'Süresi geçerli' ifadesi yalnızca exp'in geçmediğini anlatır; token'ın sunucuda kabul edileceğini göstermez.
Çözmek doğrulamak değildir
Bir JWT'nin içeriğini çözmek için anahtar gerekmez, imzanın geçerliliğini sınamak için gerekir. HS256 gibi HMAC algoritmalarında paylaşılan gizli anahtar, RS256 veya ES256 gibi algoritmalarda yayınlayanın açık anahtarı lazımdır. Herkes istediği payload'la bir token üretebilir; bu yüzden çözülmüş bir token'da 'role: admin' görmek hiçbir şey kanıtlamaz. JWT Decoder imza kontrolü yapmaz, yalnızca içeriği gösterir.
Sunucu tarafında neye bakılması gerektiğini RFC 8725 (JWT için en iyi uygulamalar) özetler. Kütüphane, kabul edilen algoritmaları uygulamanın belirlemesine izin vermeli ve header'daki alg değerine körü körüne güvenmemelidir. 'none' algoritması, token başka bir yolla korunmuyorsa kullanılmamalıdır. Birden fazla alıcıya token üreten yayınlayıcılar aud iddiası koymalı, alıcılar da bunu denetlemelidir. kid, jku ve x5u gibi header alanlarına da körü körüne güvenilmemelidir. İncelediğiniz bir token'ın header'ında alg: none görüyorsanız bu, sistemi ayrıca incelemek için yeterli bir işarettir.
Algoritma türü, doğrulamanın kimde yapılabileceğini de belirler. HS256 gibi simetrik algoritmalarda token'ı üreten ve doğrulayan aynı gizli anahtarı paylaşır; bu anahtarı bilen herkes geçerli token da üretebilir. RS256 ve ES256 gibi asimetrik algoritmalarda imza özel anahtarla atılır, doğrulama ise açık anahtarla yapılır. OpenID Connect sağlayıcıları açık anahtarlarını genellikle JWKS adı verilen bir JSON belgesinde yayımlar; header'daki kid değeri hangi anahtarın kullanılacağını gösterir.
Payload'ın okunabilir olması veri tasarımını da etkiler. T.C. kimlik numarası, telefon veya adres gibi kişisel verileri imzalı bir JWT'ye koymak, bu verileri token'ın geçtiği her log kaydına, tarayıcı deposuna ve ağ kaydına açmak demektir. Kimliği temsil etmek için anlamsız bir kullanıcı kimliği yeterlidir. RFC 8725 ayrıca farklı amaçlarla üretilen token'ların birbirinin yerine kullanılmasını önlemek için typ alanıyla açık tür belirtilmesini önerir.
Adım adım kullanım ve sık hatalar
Token'ı genellikle tarayıcının geliştirici araçlarındaki Ağ (Network) sekmesinden, bir isteğin Authorization başlığında 'Bearer' kelimesinden sonra bulursunuz. Kaydedilmiş bir ağ oturumu (.har dosyası) varsa HAR görüntüleyiciyle istekleri gezip ilgili başlığı kopyalayabilirsiniz. Kopyaladığınız metni JWT Decoder'daki alana yapıştırmanız yeterlidir; header, payload ve zaman alanları anında görünür.
Yalnızca token'ın kendisini yapıştırın. Başında 'Bearer ' kaldığında boşluk karakteri Base64URL alfabesinde olmadığından çözme hatası alırsınız. JSON'dan kopyalarken gelen tırnak işaretleri ve terminalden kopyalarken araya giren satır sonları da aynı sonucu doğurur. 'Geçersiz JWT' uyarısı, metinde hiç nokta olmadığını gösterir. Bu durumda elinizdeki büyük olasılıkla opak bir erişim belirtecidir; OAuth 2.0 erişim belirteçlerinin JWT biçiminde olması zorunlu değildir.
Token alanına yazılan metin bu araç tarafından hiçbir sunucuya gönderilmez, çözme işlemi tarayıcınızda yapılır. Yine de süresi dolmamış bir token bir parola gibidir: onu ele geçiren, süre bitene kadar sizin adınıza API çağrısı yapabilir. Canlı token'ları ekran görüntüsüne, destek talebine ya da sohbet uygulamasına koymayın; yanlışlıkla paylaştıysanız oturumu kapatıp yenisini alın.
Hata ayıklarken işe yarayan bir karşılaştırma yöntemi de var: çalışan ve çalışmayan iki isteğin token'larını ayrı ayrı çözüp header ve payload alanlarını yan yana koyun. Farklı bir aud değeri, eksik bir scope ya da farklı bir kid, sorunun kaynağını çoğu zaman tek bakışta gösterir. Tarihlerin tarayıcı saat dilimine göre gösterildiğini, sunucu loglarının ise sıklıkla UTC tuttuğunu karşılaştırma sırasında hesaba katın
Bu rehberdeki araçlar
Anlatılan işlemleri hemen tarayıcınızda, dosyanız sunucuya yüklenmeden yapın:
Sık sorulan sorular
Token'ların çoğu neden eyJ ile başlıyor?
Header bir JSON nesnesidir ve genellikle {"alg" diye başlar. Bu karakterlerin Base64URL karşılığı eyJ ile başladığı için token'lar da çoğunlukla böyle görünür.
exp tarihi on binli yılları gösteriyor. Token bozuk mu?
Büyük olasılıkla değer saniye yerine milisaniye cinsinden yazılmış. Standart saniye ister; bu durumu token'ı üreten sistemin geliştiricisine bildirin.
Araç 'süresi geçerli' diyor ama API 401 döndürüyor. Neden?
Araç yalnızca exp'e bakar. Sunucu imzayı, aud ve iss değerlerini, nbf zamanını, anahtar değişimini veya token'ın iptal edilip edilmediğini de denetleyebilir; bunların herhangi biri reddetme nedeni olabilir.
JWE (şifreli) token'ların içeriği görülebilir mi?
Anahtar olmadan hayır. JWE beş parçalıdır ve içerik şifrelidir; yalnızca ilk parça olan header okunabilir. Bu araç JWE çözmez.
