JWT Yapısı Açıklandı: Header, Payload ve Signature
Web geliştirmenin modern çağında, istemciler ve sunucular arasındaki iletişimi güvence altına almak çok önemlidir. JSON Web Token'ları (JWT), iki taraf arasında iddiaları (claims) güvenli bir şekilde temsil etmek için endüstri standardı haline gelmiştir. İster tek sayfalık bir uygulama (SPA), ister bir mobil uygulama veya bir mikro hizmet mimarisi oluşturuyor olun, JWT'lerin nasıl çalıştığını anlamak, sağlam kimlik doğrulama ve yetkilendirme uygulamak için gereklidir.
Pek çok geliştirici JWT'leri yönetmek için kütüphaneler kullansa da, dahili yapılarını derinlemesine anlamak daha iyi hata ayıklama, güvenlik denetimi ve mimari kararlar almayı sağlar. Bu kapsamlı rehberde, bir JWT'nin üç bölümünü inceleyecek, kimlik doğrulama akışını açıklayacak ve güvenlik en iyi uygulamalarını tartışacağız.
JSON Web Token (JWT) Nedir?
JSON Web Token (JWT), taraflar arasında bilgilerin bir JSON nesnesi olarak güvenli bir şekilde iletilmesi için kompakt ve bağımsız bir yol tanımlayan açık bir standarttır (RFC 7519). Bu bilgiler dijital olarak imzalandığı için doğrulanabilir ve güvenilebilir. JWT'ler bir gizli anahtar (HMAC algoritması ile) veya RSA veya ECDSA kullanılarak bir genel/özel anahtar çifti ile imzalanabilir.
JWT'lerin "bağımsız" (self-contained) doğası en büyük avantajlarıdır. Bir kullanıcı hakkında gerekli tüm bilgileri taşırlar, bu da sunucunun her istekte kullanıcının kimliğini doğrulamak için bir veritabanını sorgulamasına gerek kalmadığı anlamına gelir. Bu, JWT'leri dağıtık sistemler ve yatay ölçeklendirme için ideal hale getirir.
Yaygın kullanım durumları şunlardır:
- Yetkilendirme: JWT kullanmanın en yaygın senaryosudur. Kullanıcı oturum açtıktan sonra, sonraki her istek JWT'yi içerecek ve kullanıcının bu belirteçle izin verilen rotalara, hizmetlere ve kaynaklara erişmesine olanak tanıyacaktır.
- Bilgi Alışverişi: JWT'ler, taraflar arasında güvenli bir şekilde bilgi iletmek için iyi bir yoldur. JWT'ler imzalanabildiği için (örneğin genel/özel anahtar çiftleri kullanılarak), gönderenlerin söyledikleri kişi olduğundan emin olabilirsiniz. Ek olarak, imza başlık ve yük kullanılarak hesaplandığından, içeriğin kurcalanmadığını da doğrulayabilirsiniz.
Bir JWT'nin Üç Parçası
Kompakt formunda, bir JSON Web Token noktalarla (.) ayrılmış üç bölümden oluşur:
- Header (Başlık)
- Payload (Yük)
- Signature (İmza)
Bu nedenle, bir JWT tipik olarak şuna benzer:
xxxxx.yyyyy.zzzzz
Neler içerdiklerini ve nasıl kodlandıklarını görmek için her bir bölümü inceleyelim. Gerçek bir belirteci incelemeniz gerekirse, içinde tam olarak ne olduğunu görmek için JWT Çözücümüzü (JWT Decoder) kullanabilirsiniz.
Bölüm 1: Header (Başlık)
Başlık genellikle iki bölümden oluşur: belirtecin türü (JWT) ve HMAC SHA256 veya RSA gibi kullanılan imzalama algoritması.
{
"alg": "HS256",
"typ": "JWT"
}
Ardından bu JSON, JWT'nin ilk bölümünü oluşturmak için Base64Url ile kodlanır. Base64Url kodlamasının şifreleme olmadığını; ikili benzeri verileri URL dostu bir dize biçiminde temsil etmenin bir yolu olduğunu unutmamak önemlidir.
alg (algoritma) alanı kritiktir. Alıcıya imzanın nasıl doğrulanacağını söyler. Ancak, bu alan geçmişte pek çok güvenlik açığının kaynağı olmuştur ("none" algoritması saldırısı gibi); bu nedenle modern kütüphaneler doğrulama sırasında beklenen algoritmaları açıkça tanımlamanızı gerektirir.
Bölüm 2: Payload (Yük/İddialar)
Belirtecin ikinci bölümü, iddiaları (claims) içeren yüktür. İddialar, bir varlık (tipik olarak kullanıcı) ve ek veriler hakkındaki ifadelerdir. Üç tür iddia vardır: kayıtlı, genel ve özel iddialar.
- Kayıtlı iddialar (Registered claims): Bunlar, zorunlu olmayan ancak bir dizi yararlı, birlikte çalışabilir iddia sağlamak için önerilen bir dizi önceden tanımlanmış iddiadır. Bazıları şunlardır:
iss(veren/issuer),exp(son kullanma süresi),sub(konu),aud(hedef kitle) ve diğerleri. - Genel iddialar (Public claims): Bunlar JWT'leri kullananlar tarafından isteğe göre tanımlanabilir. Ancak çakışmaları önlemek için IANA JSON Web Token Kayıt Defterinde tanımlanmalı veya çakışmaya dayanıklı bir ad alanı içeren bir URI olarak tanımlanmalıdır.
- Özel iddialar (Private claims): Bunlar, kayıtlı veya genel iddia olmayan ve bunları kullanmayı kabul eden taraflar arasında bilgi paylaşmak için oluşturulan özel iddialardır.
Örnek bir yük şuna benzeyebilir:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022,
"exp": 1516242622
}
Yük daha sonra JSON Web Token'ın ikinci bölümünü oluşturmak için Base64Url ile kodlanır. Geliştirme sırasında karşılaştığınız herhangi bir belirteçten bu iddiaları hızlıca çıkarmak için JWT Çözücümüzü kullanabilirsiniz.
Bölüm 3: Signature (İmza)
İmza bölümünü oluşturmak için kodlanmış başlığı, kodlanmış yükü, bir gizli anahtarı, başlıkta belirtilen algoritmayı almalı ve bunları imzalamalısınız.
Örneğin, HMAC SHA256 algoritmasını kullanmak istiyorsanız, imza şu şekilde oluşturulacaktır:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
İmza, mesajın yol boyunca değiştirilmediğini doğrulamak için kullanılır ve özel bir anahtarla imzalanmış belirteçler durumunda, JWT'yi gönderenin söylediği kişi olduğunu da doğrulayabilir. Bu, bütünlük garantisi sağladığı için JWT'nin en kritik parçasıdır.
JWT Kimlik Doğrulaması Nasıl Çalışır? (Akış)
JWT tabanlı kimlik doğrulama için tipik akış şu adımları izler:
- Giriş İsteği: İstemci, kimlik bilgilerini (örneğin kullanıcı adı ve şifre) sunucuya gönderir.
- Token Oluşturma: Sunucu kimlik bilgilerini doğrular ve doğruysa bir JWT oluşturur. Sunucu, bir gizli anahtar veya özel anahtar kullanarak JWT'yi imzalar.
- Token Yanıtı: Sunucu JWT'yi istemciye geri gönderir.
- Depolama: İstemci belirteci saklar, genellikle
localStorage'da veya birHttpOnlyçerezinde (cookie). - Sonraki İstekler: Korunan her kaynak isteği için istemci,
Bearerşemasını kullanarakAuthorizationbaşlığında JWT'yi gönderir:Authorization: Bearer <token>. - Doğrulama: Sunucu isteği alır, belirteci çıkarır ve gizli veya genel anahtarı kullanarak imzasını doğrular. İmza geçerliyse ve belirtecin süresi dolmamışsa sunucu, istenen kaynağa erişim izni verir.
Bu akış, sunucunun her kullanıcı için bellekte (veya bir veritabanı/Redis'te) bir oturum durumu tutma ihtiyacını ortadan kaldırır; bu da sunucu tarafındaki yükü önemli ölçüde azaltır ve daha iyi ölçeklenebilirlik sağlar.
Güvenlik En İyi Uygulamaları: Neden JWT'de Gizli Bilgi Tutmamalısınız?
Geliştiriciler arasındaki yaygın bir yanlış anlama, JWT'lerin hassas verileri gizlemenin güvenli bir yolu olduğudur. Bu yanlıştır. JSON Web Şifrelemesi (JWE) kullanmadığınız sürece, bir JWT'nin yükü (payload) şifrelenmiş değil, yalnızca Base64Url ile kodlanmıştır.
Belirteci ele geçiren herkes yükü kolayca çözebilir ve içindeki bilgileri okuyabilir. Bu nedenle, yükte asla şifreler, sosyal güvenlik numaraları veya diğer hassas gizli bilgileri saklamamalısınız. İmzalama işleminiz için güçlü sırlar kullandığınızdan emin olmak üzere, yüksek entropili anahtarlar oluşturmak için Şifre Oluşturucumuzu (Password Generator) kullanabilirsiniz.
Temel güvenlik ipuçları:
- Her zaman HTTPS kullanın: Belirteçlerinizin çalınmasını önlemek için Ortadaki Adam (MITM) saldırılarına karşı koruma sağlayın.
- Süreyi kısa tutun: Bir belirteç çalınırsa saldırganın fırsat penceresini en aza indirmek için kısa bir son kullanma süresi (
expiddiası) ayarlayın. - HttpOnly Çerezleri Kullanın: JWT'leri tarayıcıda saklıyorsanız, çerezlerde
HttpOnlyveSecurebayraklarını kullanmak Cross-Site Scripting (XSS) saldırılarına karşı korunmaya yardımcı olur. - Algoritmayı Doğrulayın:
algbaşlığına körü körüne güvenmeyin. Doğrulama mantığınızda beklenen algoritmayı sabit olarak belirleyin.
JWT vs. Oturum Çerezleri: Temel Farklar
JWT ve geleneksel oturum çerezleri arasındaki seçim uygulamanızın gereksinimlerine bağlıdır. İşte bir karşılaştırma:
| Özellik | Oturum Çerezleri (Session Cookies) | JSON Web Token'ları |
|---|---|---|
| Durum | Stateful (sunucuda saklanır) | Stateless (istemcide saklanır) |
| Ölçeklenebilirlik | Daha zor (yapışkan oturumlar veya paylaşımlı depo gerektirir) | Daha kolay (tamamen bağımsız) |
| İptal Etme | Kolay (sunucudan silin) | Zor (bir kara liste veya kısa süre gerektirir) |
| Boyut | Küçük (yalnızca bir oturum kimliği) | Büyük (tüm iddiaları içerir) |
Yaygın JWT Algoritmaları (HS256 vs RS256)
JWT'lerle kullanılan iki temel imzalama algoritması türü vardır: simetrik ve asimetrik.
HS256 (SHA-256 ile HMAC) simetrik bir algoritmadır; yani hem belirteci imzalamak hem de doğrulamak için aynı gizli anahtar kullanılır. Uygulaması basittir ancak hem verenin hem de tüketicinin sırrı güvenli bir şekilde paylaşmasını gerektirir.
RS256 (SHA-256 ile RSA İmzası) asimetrik bir algoritmadır; yani belirteci imzalamak için özel bir anahtar, doğrulamak için ise genel bir anahtar kullanılır. Belirteci veren hizmetin belirteci tüketen hizmetten farklı olduğu senaryolar (örneğin Google veya Auth0 gibi OAuth2 sağlayıcıları) için daha güvenlidir.
| Algoritma | Tür | Anahtar Gereksinimleri | En İyi Kullanım |
|---|---|---|---|
| HS256 | Simetrik | Bir paylaşılan gizli anahtar | Dahili uygulamalar, küçük ekipler |
| RS256 | Asimetrik | Özel anahtar (imza), Genel anahtar (doğrulama) | Mikro hizmetler, Genel API'ler, Kimlik Sağlayıcılar |
Sonuç
JSON Web Token'ları, modern web uygulamalarında kimlik doğrulamayı yönetmek için güçlü ve esnek bir yol sunar. Üç parçalı yapıyı (Header, Payload ve Signature) anlayarak geliştiriciler hem ölçeklenebilir hem de güvenli sistemler oluşturabilirler. Ancak, JWT'lerin gizlilik için değil, bütünlük ve kimlik doğrulama araçları olduğunu unutmamak hayati önem taşır.
JWT'leri uygularken her zaman güçlü imzalama anahtarları kullanarak, HTTPS'yi zorunlu kılarak ve yükleri hafif tutarak güvenliğe öncelik verin. İster JWT Çözücümüzle bir belirteci hata ayıklıyor olun ister Şifre Oluşturucumuzla yeni bir sır oluşturuyor olun, doğru araçlara ve bilgiye sahip olmak harika yazılımlar oluşturmanın ilk adımıdır.