JWT Nedir?

Ensar Makas
6 min readOct 21, 2022

JSON Web Token (JWT), taraflar arasında bir bilgiyi, JSON objesi şeklinde güvenle taşımak için geliştirilen, bunun için kompakt ve bağımsız yöntem tanımlayan bir açık kaynak standartıdır. (RFC 7519)

Bu taşınan bilgi, dijital imzalı olduğundan güvenilebilir ve onalyanabilir bir bilgidir.

JWT’ler, gizli anahtar (HMAC algoritması ile) veya RSA ya da ECDSA algoritmaları kullanan özel-genel anahtar çiftleri kullanılarak imzalanabilirler.

JWT’lerin ayrıca partiler arasında gizlilik sağlanması için şifrelenebilmesi bir yana, bizim odaklanacağımız konu imzalı belirteçler (signed tokens) olacak. İmzalı belirteçler, içerisinde barındırdığı isteklerin bütünlüğünü onaylayabilirler. Bunun yanında bu istekleri de diğer taraflardan gizli tutarlar. Belirteçler özel-genel anahtar çiftleri ile imzalandığında bu imza, sadece özel anahtarın sahibi olan tarafın onu imzaladığını da tasdikler.

JSON Web Token’lar ne zaman kullanılmalıdır?

JWT’lerin (JSON Web Token) kullanımının faydalı olduğu bazı senaryolar şu şekildedir.

  • Yetkilendirme: Bu tür senaryolar JWT’lerin en sık kullanıldığı türden senaryolardır. Kullanıcı giriş yaptığında, sonrasında yaptığı tüm istekler JWT içerir. Bu, kullanıcılara o belirteç (token) ile sınırlandırılmış veb sayfaları, servisler ve kaynaklara erişim sağlar.
    Single Sign On, bu günlerde, küçük ek yükü ve diğer domainlerce kolay kullanıma sahip olması sebebiyle JWT’yi sıkça kullanılan bir özelliktir
  • Bilgi alışverişi: JSON Web Token’leri (JWT) bilgileri taraflar arasında aktarmanın güvenli bir yoludur. Çünkü JWT’ler imzalı olduğundan, (Örneğin özel-genel anahtar çiftleri ile imzalanmış) Göndericilerin kim olduğu açık olur. Buna ek olarak, imza ‘header’ ve ‘payload’ bölümü kullanılarak hesaplandığından, içeriğin kurcalanmadığı da garantilenmiş olur.

JSON Web Token’inin yapısı nasıldır?

JSON Web Token’leri ‘ . ’ ile birbirinden ayrılan üç bölümden oluşur. Bunlar:

  • Header
  • Payload
  • Signature

Şeklinde adlandırılır. Bu yüzden tipik bir JWT şu şekilde gözükür:

xxxxx.yyyyy.zzzzz

Bu parçaları biraz inceleyelim

Header

Başlık, genelde iki bölümden oluşur. Belirteçin tipi, (JWT) ve kullanılan imzalama algoritması. (HMAC, SHA256 ya da RSA)

Örnek:

{ "alg":"HS256", "type": "JWT" }

Sonrasında, bu JSON nesnesi, Base64Url formatıyla kodlanır ve JWT nin ilk kısmında yer edinir.

Payload

JWT belirtecinin bir sonraki bölümüne de “faydalı yük” ya da “yararlı yük” adı verilmektedir. Namı değer payload. Adından da anlaşılabileceği şekilde, belirteç içerisindeki isteği taşır. Bu istekler, bir varlık (genellikle kullanıcıdır) ve ek verilerle ilgili ifadelerdir. Bu noktada üç tip istek karşımıza çıkar. Bunlar “registered”, “public” ve “private” isteklerdir.

  • Registered Claims: Bu istekler önceden tanımlanmış istekler dizisidir. Zorunlu değillerdir ancak tavsiye edilirler. Bu istekler yararlı, uyumlu bir takım istekler sunmak amacıyla oluşturulmuştur. Bunlardan bazıları: iss (belirteci veren) exp (sona erme tarihi) sub (konu) ve aud (hedef kitle) şeklindedir. Diğer isteklere buradan ulaşabilirsiniz.

Unutmayın ki istek isimleri sadece üç harf uzunluğundadır.
Çünkü JWT, kompakt olmak için vardır

  • Public Claims: Bu istekler JWT’yi kullanan taraflara göre tanımlanabilir. Fakat çelişmeleri önlemek amacıyla tanımlamalar IANA JSON Web Token Registry’ de tanımlı olması gereklidir. Ya da çelişkiye sebebiyet vermeyecek bir isim uzayından uri olarak tanımlanmalıdır.
  • Private Claims: Bu istekler taraflarca bilgiyi aktarmak amacıyla kendi aralarında tanımladıkları, ne “public”, ne de “registered” türünde olan isteklerdir.

Payload’a örnek olabilecek bir JSON nesnesi:

{ "sub": "1234567890", "name": "John Doe", "admin": true }

Bu JSON nesnesi de, tıpkı “header” da olduğu gibi Base64URL ile kodlanıp JWT yapısının ikinci bölümüne yerleşir.

İmzalı belirteçler hakkında şu unutulmamalıdır ki bilgiler, değiştirilmeye karşı korumalıdır ancak herkes tarafından okunabilir durumdadır. Gizli bilgiler şifreli olmadıkça JWT’nin başlık veya faydalı yük bölümlerinin içerisinde barındırmayın.

Signature

Bu kısmı oluşturmak için öncelikle kodlanmış “header” kısmı, kodlanmış “payload” kısmı ve bir gizli¹ alınıp “header” kısmında tanımlanan algoritma ile imzalanır.

Örneğin, eğer HMAC SHA256 algoritması ile şifrelenecek olursa, imza şu şekilde hazırlanabilir

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

İmza, mesajın yol boyunca değişime uğramadığından emin olmak için kullanılır. Ve belirtecin özel bir anahtarla imzalandığı durumda bu imza, JWT’yi gönderenin iddia edilen taraf olup olmadığının da göstergesi olur.

Sonuç

Sonunda çıktımız, HTML ve HTTP ortamlarına kolayca aktarılabilen, nokta ile birbirinden ayrılmış üç adet Base64-Url karakter dizgisi oluyor. Bu dizgi, SAML gibi XML tabanlı standartlarla kıyaslandığında daha kompakt bir yapıda kalıyor.

Aşağıdaki görsel, yukarıdaki “header” ve “payload” kısmının kodlanmış halini, ve bunların bir gizli ile imzalanmış halini içeren bir JWT’yi gösteriyor.

Eğer JWT’yi daha da kurcalamak ve burada öğrendiklerinizi pratiğe dökmek isterseniz, jwt.io Debugger adresini ziyaret ederek yeni belirteçler oluşturabilir ve inceleyebilirsiniz.

JSON WEB Tokenleri nasıl çalışır?

Kimlik doğrulama aşamasında, kullanıcı başarılı bir giriş yaptığında Bir tane JWT (JSON Web Token) döndürülür. Tokenler (belirteçler) bir ehliyet² görevi gördüğünden, güvenlik açıklarını önlemek için bu belirteçlere büyük özen gösterilmelidir. Genellikle bu belirteçler, gereğinden uzun boyutta olmamalıdır.

Ayrıca, hassas oturum bilgilerini tarayıcı depolama alanında tutmamalısınız. Bu bir güvenlik zaafiyetidir.

Kullanıcı her kaynak korumalı yola veya kaynağa erişmek istediğinde, kullanıcı tarafı bir JWT belirteci gönderir. Bu JWT, genellikle istek başlıklarında (header) Authorization başlığı içinde Bearer şeması ile beraber bulunur.

Yani istek başlığının içeriği şu şekilde olur:

Authorization: Bearer <token>

Bazı senaryolarda bu, bir durumsuz kimlik doğrulama mekanizması³ olabilir. Sunucunun korunmuş yolları⁴, “Authorization” başlığı içerisindeji JWT belirtecinin doğruluğunu kontrol eder. Eğer böyle bir belirteç bulunuyorsa, kullanıcıya kaynağa erişimi için izin verilir. Eğer JWT içerisinde gerekli bilgiler varsa, bu durum veritabanı içerisindeki gerekli sorgu işlemlerinin azalmasına yardımcı olabilir. Fakat bu durum her zaman böyle olmayabilir.

Unutulmamalıdır ki, eğer JWT belirteçleri HTTP üzerinden gönderileceklerse boyutlarının çok büyük olmamaları gerekir. Bazı sunucular, isteklerindeki başlıklar için en fazla 8 KB alan ayırır. Eğer JWT belirteci içerisine çok fazla veri gömmeye çalışıyorsanız, mesela tüm kullanıcı verilerini gömmek gibi, bu durumda “Auth0 Fine-Grained Authorization” gibi farklı çözümler işinize yarayacaktır.

Eğer belirteç, Authorization başlığı içerisinde gönderilmişse, “Cross Origin Resource Sharing (CORS)”⁵, Cookie⁶ kullanmadığından bir sorun teşkil etmeyecektir.

Aşağıdaki diyagram, JWT’lerin kaynaklara veya API’lara⁷ erişebilmek için nasıl kullanıldığını gösteriyor

  1. Uygulama veya istemci, Yetkilendirme servisinden bir istekte bulunur. Bu yöntem, bir sürü farklı yetkilendirme yöntemlerinden herhangi biri olabilir. Örneğin, sıradan bir OpenID Connect uyumlu bir web uygulaması, “authorization code flow” akışına göre doğruca oauth/authorize uç noktasına gider.
  2. Eğer yetkilendirme işlemi başarı ile sonuçlanmışsa Yetkilendirme servisi, istemciye bir erişim belirteci (access token) gönderir.
  3. Uygulama, korunmuş kaynaklara erişmek için yetkilendirme servisinden aldığı bu erişim belirtecini kullanır.

İmzalı belirteçlerin içlerinde bulunan her mesaj, her ne kadar değiştirilmeye karşı korunmuş olsa da diğer kullanıcı veya taraflarca okunabilir durumdadır. Dolayısıyla belirteçlerin içerisine hassas bilgilere yer vermeyin.

Neden JWT kullanmalıyız?

Biraz JWT’nin SWT’lere (Simple Web Token) ve SAML’lere (Security Assertion Markup Language Tokens) kıyasla faydalarından bahsedelim.

JSON, XML’e kıyasla daha az ayrıntılı olduğundan, kodlanmış boyutları da kıyaslandığında JSON daha az boyutlu ve kompakt olarak karşımıza çıkar. Dolayısıyla JWT’ler de SAML’lere kıyasla boyut olarak daha düşük ve kompakt olurlar. Dolayısıyla JWT’yi HTTP ve HTML ortamlarında kullanmak daha avantajlıdır.

Güvenlik açısından, SWT ler sadece paylaşılabilir genel (public) anahtarlarla HMAC algoritması ile simetrik olarak imzalanabilir. Öte yandan JWT ve SAML’ler, özel — genel anahtar çiftleriyle asimetrik olarak X.509 sertifika formunda şifrelenebilirler. XML’i XML Digital Signature ile güvenlik açıkları meydana gelmeden imzalamak, JSON’un imzalanma basitliğinin yanında çok zordur.

JSON çözümleyicileri (parsers) çoğu programlama dilinde ortaktır. Çünkü JSON dosyasını direkt objelerle eşleştirirler. Aksine, XML için dahili bir “dökümandan nesneye (document to object)” eşlemesi yoktur. Bu da JWT’yi SAML’ye kıyasla üzerinde çalışması daha kolay bir çözüm yapar.

Kullanıma bakılacak olursa, JWT internet ölçeğinde kullanılıyor. Bu durum da JWT’nin özellikle mobil gibi çoklu platformlarda istemci tarafında işlenmesinin kolaylığını vurguluyor.

Kodlanmış JWT ve kodlanmış SAML karakter dizgilerinin uzunluk kıyaslaması

Eğer JSON Web Tokens hakkında daha fazla şey okumak, ya da kendi uygulamalarınızda yetkilendirme işlemleri için kullanmaya başlamak isterseniz, Auth0'daki JSON Web Token landing page sayfasını ziyaret edebilirsiniz.

Kaynakça

Dip Not

  1. Gizli (Secret): İmzalama veya şifreleme sırasında kullanılan bir anahtar sözcüktür.
  2. Ehliyet (Credential): Korunmuş kaynaklara erişebilmek için yetkilendirme servislerinden size verilen anahtardır.
  3. Durumsuz kimlik doğrulama mekanizması (Stateless Authentication Mechanism): Bu mekanizma, kullanıcı özellikleri gibi birçok oturum bilgilerini istemci tarafında tutarak kullanıcı kimliklerini doğrulama yöntemidir. (https://www.hypr.com/security-encyclopedia/stateless-authentication)
  4. Yol (Route): Web uygulaması içerisindeki erişilebilir kaynağın yoludur.
  5. Cross Origin Resource Sharing: Farklı web uygulamalarının (domain) sizin uygulamanızın kaynaklarına erişip erişememe durumunuz. (https://devnot.com/2019/cors-nedir/) (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
  6. Cookie: Bir web uygulamasında oturum açtığınızda oluşturulan oturum bilgilerinize verilen isim.

--

--

Ensar Makas

Beykent Üniversitesi Bilgisayar Mühendisliği ve aynı zamanda Ecole 42 Türkiye'de ana eğitim öğrencisi