Tek adımda çözme
Bir JSON Web Token şuna benzer: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMifQ.imza; noktalarla birleştirilmiş üç Base64url metni. Her JWT eyJ ile başlar, çünkü {" karakterleri Base64'te böyle görünür.
Token'ı aşağıdaki araca yapıştır. Authorization başlığından kopyalanan Bearer ön eki sorun değil. Başlığı ve içeriği biçimlendirilmiş JSON olarak, exp, iat, nbf ve auth_time claim'lerini yerel saatinle ve ne kadar önce ya da sonra olduğuyla tarih olarak görürsün; durum satırı token'ın süresinin dolup dolmadığını ya da henüz geçerli olup olmadığını söyler. İmzayı kontrol etmek için paylaşılan gizli anahtarı ya da açık anahtarı Gizli ya da açık anahtar (isteğe bağlı) alanına yaz.
Burada dene: JWT çözücü
Aracın tam sayfasını açJWT'nin üç parçası
- Başlık (header): {"alg":"HS256","typ":"JWT"} gibi küçük bir JSON. alg imza algoritmasını söyler; varsa kid hangi anahtarın kullanıldığını belirtir, yayıncı anahtarlarını değiştirdiğinde işe yarar.
- İçerik (payload): claim'ler, yani kullanıcı ve token hakkındaki bilgiler: kullanıcı kimliği, yayıncı, hedef kitle, roller, bitiş zamanı gibi. Token'ı elinde tutan herkes bunları okuyabilir.
- İmza (signature): kodlanmış başlık ve içerik üzerinden bir gizli anahtarla (HMAC) ya da özel anahtarla (RSA veya eliptik eğri) hesaplanır. İlk iki parçanın değişmediğini ve anahtarı elinde tutan biri tarafından verildiğini kanıtlar.
- Üç yerine beş parçalı bir token şifreli bir JWE'dir. İçeriği özel anahtar olmadan okunamaz; böyle bir token yapıştırdığında araç bunu söyler.
Sık kullanılan claim'ler ve anlamları
JWT standardı (RFC 7519) birkaç kısa claim adı tanımlar. Zamanlar NumericDate değeridir: 1 Ocak 1970 UTC'den bu yana geçen saniye, milisaniye değil. Bunları karıştırmak klasik bir hatadır; örneğin exp'i milisaniye döndüren JavaScript Date.now() ile karşılaştırmak.
| Claim | Adı | Anlamı |
|---|---|---|
| iss | Issuer (yayıncı) | Token'ı kim oluşturdu, genelde kimlik sağlayıcının adresi |
| sub | Subject (konu) | Token kimin hakkında, genelde kullanıcı kimliği |
| aud | Audience (hedef) | Hangi API ya da uygulama kabul etmeli |
| exp | Expiration (bitiş) | Bu andan sonra token reddedilmeli |
| nbf | Not before (başlangıç) | Bu andan önce token henüz geçerli değil |
| iat | Issued at (oluşturulma) | Token'ın oluşturulduğu an |
| jti | JWT ID | Tekil kimlik; tekrar kullanımı engellemek ya da iptal için |
| auth_time | Giriş zamanı | Kullanıcının gerçekten giriş yaptığı an (OpenID Connect) |
Elle ya da kodla çözme
Base64url standart Base64'ten farklıdır: + ve / yerine eksi ve alt çizgi kullanır, = dolgusu silinir. Çözme hatalarının çoğu, JWT parçasını doğrudan standart bir Base64 çözücüye vermekten gelir. Eksiyi + ile, alt çizgiyi / ile değiştir, uzunluk 4'ün katı olana kadar = ekle, sonra çöz.
Python'da base64.urlsafe_b64decode(parca + "==") alfabeyi halleder, fazla dolguyu da sorun etmez. Tarayıcı konsolunda iki karakteri değiştirdikten sonra atob çalışır ama baytları Latin 1 olarak döndürür; içerikteki Türkçe isimlerin (Şükrü, Gülşen gibi) doğru görünmesi için UTF-8'e TextDecoder ile çevirmek gerekir. Python'da PyJWT, Node.js'te jsonwebtoken, .NET'te System.IdentityModel.Tokens.Jwt gibi kütüphaneler çözme ve doğrulamayı tek çağrıda yapar; canlı sistemde sadece çözen kısayolu değil, doğrulayan fonksiyonu kullan.
Hızlıca bakmak için araç daha pratiktir ve token'ı komut geçmişinde bırakmaz.
Çözmek doğrulamak değildir
İçeriği okumak token'ın ne iddia ettiğini söyler, iddiaların doğru olduğunu kanıtlamaz. Herkes "role": "admin" yazan bir token oluşturup Base64 ile kodlayabilir. İçeriği güvenilir yapan tek şey doğru anahtarla kontrol edilmiş geçerli bir imzadır. Sunucular hiçbir claim'i kullanmadan önce mutlaka doğrulama yapmalı.
Araçta HS256, HS384 ve HS512 token'ları paylaşılan gizli anahtarla doğrulanır. RS, PS ve ES token'ları yayıncının PEM biçimindeki açık anahtarıyla, yani BEGIN PUBLIC KEY ile başlayan blokla doğrulanır. Kimlik sağlayıcın anahtarları sadece JWKS listesi olarak yayınlıyorsa önce uygun anahtarı (kid değeri başlıktakiyle aynı olanı) PEM'e çevir. Sonuç İmza geçerli ya da İmza anahtarla eşleşmiyor olarak görünür. Özel anahtar yapıştırırsan araç onun yerine açık anahtarı ister.
Şu uyarı işaretlerine dikkat et: alg değerinin none olması (token'da hiç imza yoktur, araç imzasız olarak işaretler), beklenmeyen bir algoritma (RS256 bekleyen bir sunucu HS256 token'ı asla kabul etmemeli, bilinen bir saldırıdır) ve iss ya da aud değeri senin sisteminle uyuşmayan token'lar.
Süresi dolmuş ve geçersiz token sorunları
- Süresi doldu: Tarihler bölümündeki bitiş tarihine bak. Erişim token'ları genelde bilerek sadece 5 ile 60 dakika yaşar; uygulama yenisini almak için refresh token kullanmalı.
- Henüz geçerli değil: nbf ya da iat ileri bir tarihte; bu genelde sunucu saatiyle yayıncının saatinin farklı olduğunu gösterir. Birçok kütüphane birkaç saniyeden birkaç dakikaya kadar küçük bir saat farkına izin verir; saati otomatik zaman eşitlemesiyle düzelt.
- Bu bir JWT'ye benzemiyor: token kesilmiş, tırnak içine alınmış ya da kopyalarken boşluk girmiş. Asıl başlıktan ya da çerezden yeniden kopyala.
- Başlık ya da içerik okunamadı: token'ın bir kısmı eksik. Uzun token'lar loglarda sık sık kırpılır.
- İmza eşleşmiyor: yanlış gizli anahtar, başka bir ortamın (test ve canlı) açık anahtarı, değiştirilmiş bir anahtar ya da üzerinde oynanmış bir token.
Token'ları güvenle kullan
Geçerli bir erişim token'ı süresi dolana kadar şifre gibi çalışır. Canlı sistem token'larını onları sunucuya gönderen sitelere yapıştırma, destek kayıtlarına ya da sohbet gruplarına yazma. Bu çözücü tamamen tarayıcında çalışır: token gönderilmez, kaydedilmez, saklanmaz.
Token üreten tarafta içeriği küçük ve gizli bilgiden arınmış tut. Herkes okuyabildiği için JWT'ye asla şifre, API anahtarı ya da istemcinin görmemesi gereken kişisel veri koyma. Kullanıcı kimliğini ve rolleri sakla, gerisini sunucuda sorgula.