JWT (JSON Web Token) Nedir?

Jer bir projede kullanıcı kimliklendirilmesi işlemlerinde vazgeçilmez unsurlardan biri token yapısıdır. Genel senaryo şudur:

  1. İstemci kullanıcı adı ve parola ile birlikte sunucuya login isteği gönderir.
  2. Sunucu bu bilgileri alarak veri tabanından sorgulama yapar ve kullanıcı adı ile kendi gizli anahtarını birleştirip bir özet fonksiyonundan geçirir. Fonksiyon sonucu token döner ve sunucu bu bilgiyi veri tabanında ilgili kullanıcının TOKEN kolonuna yazar.
  3. Sunucu token’ı istemciye iletir.
  4. İstemci bundan sonraki her işlemde bu token’ı kullanarak gönderim gerçekleşir ve sunucu tarafında her defasında veri tabanından token’ın geçerli olup olmadığını kontrol edilir.

İstemci her defasında ad/parola ikilisini sunucuya göndermek zorunda kalmadığı gibi kendi tarafında parola bilgisinin tutulması yerine sunucuda oluşturulan token bilgisini tutmasıyla daha güvenli bir yapı oluşturulmuş olur. Fakat burada 2 farklı konu karşımıza çıkıyor:

  1. Token her sunucu işlemi için veri tabanından kontrol ediliyor. 1 birimlik işiniz varsa 2 birimlik iş yapmış oluyorsunuz.
  2. Standart bir yapı/algoritma olmadığı için oluşturulacak token güvenliği/implementasyonu ayrı bir tartışma konusu haline geliyor.

Bu sorunları aşmanın yollarından biri de bu yazının konusu olan JSON Web Token (JWT) kullanmaktan geçiyor.

JSON Web Token nedir?

JSON Web Token (JWT), iletişim yapan birimler arasındaki veri alışverişinin güvenli bir şekilde sağlanması için bir JSON nesnesi (token) kullanarak daha kompakt ve bilginin kendini kendini betimlediği bir yol sunan endüstri standardıdır (RFC 7519). Oluşturulan token, dijital olarak imzalandığı için doğrulanabilir ve güvenilirdir. Bir JWT, HMAC algoritması ve gizli bir kelime kullanılarak imzalanabilir. İmzalama sürecinde HMAC yerine RSA algoritmasından yararlanılarak açık ve gizli anahtar ikililerinin kullanılması da sağlanabilir. JWT’nin özelliklerine biraz daha değinelim:

  • Kompakttır: Boyutunun küçük olması sayesinde URL üzerinden gönderilebilir, POST parametresi olarak eklenebilir veya HTTP başlığı içerisinde yer alabilir. Kompakt olmasının diğer bir avantajı ise aktarımın hızlı gerçekleşmesidir.
  • Kendi-kendini betimler: Token içerisinde isteği yapan kullanıcı ile ilgili gerekli bütün bilgi mevcuttur. Bu sayede kimliklendirme için veri tabanında birden fazla sorgu yapılması engellenmiş olur. Daha fazla detaylı bilgi için JWT Handbook‘a bakabilirsiniz.

Ne zaman JWT kullanmalısınız?

Aşağıdaki kısımda JSON Web Token’ın faydalı olduğu senaryolar yer almaktadır:

  • Kimliklendirme: Aslında en temel kullanım senaryosu budur. Kullanıcının başarılı yaptığı giriş işlemi sonrasında gerçekleştireceği her istek JWT’yi içerir. Bu sayede kullanıcının hangi kaynaklara/web sayfalarına erişeceği bu token bilgisi ile kontrol edilir. Farklı domain’ler arasında kolayca token değiş-tokuşunu sağladığı için, tek seferlik giriş (single sign on) senaryolarında yoğun olarak kullanılmaktadır.
  • Bilgi değiş-tokuşu: JWT’ler dijital olarak imzalanabildiği için bilginin iletişim yapan birimler arası güvenli bir şekilde gerçekleşebilmesi için iyi bir yöntem sunar. Örneğin açık/gizli anahtar ikilileri kullanıldığında bilgiyi gönderen kişinin gerçekte kim olduğunu söylemek mümkündür. Buna ek olarak, JWT’deki header ve payload kısımları dahil edilerek oluşturulan imza sayesinde gelen bilginin değiştirilip/değiştirilmediği kolayca doğrulanabilir.

JWT’nin yapısı

JWT’ler birbirine nokta (.) ile bağlanan 3 kısımdan oluşur:

  • Hedaer (Başlık)
  • Payload (Yük)
  • Signature (İmza)

Böylece tipik bir JWT aşağıdaki gibi görünür:

xxxxx.yyyyy.zzzzz

Haydi bahsettiğimiz kısımlara değinelim.

Header (Başlık)

Başlık genellikle 2 parçadan oluşur:

  1. typ: Token’ın türünü belirler. “JWT” değerine sahiptir.
  2. alg: Kullanılan özet (hash) algoritmasını gösterir. HMAC SHA256 veya RSA gibi değerler alabilir. Örnek bir header aşağıdaki şekildedir:
{
  "alg": "HS256",
  "typ": "JWT"
}

Daha sonra bu JSON bilgisi Base64Url ile kodlanarak JWT’nin ilk parçasını oluşturur.

Payload (Yük)

Token’ın ikinci parçası olan payload, ilgili claim‘leri içerir. Claim’ler kullanıcı hakkında bilgiler sunan ifadelerdir. Ayrıca metadata bilgisi de içerebilir. reservedpublic ve private olmak üzere 3 tip claim bulunmaktadır:

  • Reserved (Ayrılmış) claim’ler: Önceden tanımlanmış claim’lerdir. Kullanılması zorunlu değildir fakat önerilir. Yararlıdırlar ve birlikte çalışabilen bir claim kümesinin oluşturulmasını sağlarlar. Bunlardan bazıları: iss (issuer) (yayınlayıcı), exp(expiration time) (son kullanım zamanı), sub (subject) (konu), aud (audience) (hedef kitle) ve diğerleridir. Not: Farkettiğiniz gibi kompakt olması açısından claim isimleri yalnızca 3 karakter uzunluğundadır.
  • Public (Açık) claim’ler: İsteğe göre eklenen alanlardır. Fakat rezerve edilmiş IANA JSON Web Token kayıtları veya URI’da tanımlanan parametreler ile kullanımın çakışmasından kaçınılmalıdır.
  • Private (Gizli) claim’ler: Bilgi paylaşımı için tarafların kendi aralarında anlaştığı özel claim’lerdir.

Üstteki 3 claim bilgisine dayanarak örnek bir payload aşağıdaki şekilde oluşturulabilir:

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

Daha sonra bu JSON bilgisi Base64 ile kodlanarak JWT’nin ikinci parçasını oluşturur.

Signature (İmza)

Signature kısmının oluşturulabilmesi için base64 ile kodlanmış header, base64 ile kodlanmış payload, gizli bir kelime (secret) ve header’da tanımlanan algoritma gereklidir.

Örneğin HMAC SHA256 algoritması kullanılarak aşağıdaki şekilde imza oluşturulabilir:

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

Oluşturulan imza, JWT’yi gönderenin kim olduğunu belirtir ve iletim yapılan bilginin göndericiden alıcıya gelene kadar değişip değişmediğinin kontrolünde kullanılır.

Şimdi öğrendiklerimizi bir araya getirelim

Base64 string ifadelerinin nokta ile birleştirilmesiyle oluşan JWT, SAML gibi XML-temelli daha karmaşık standartların aksine HTML ve HTTP ortamlarında kolayca üretilebilir.

Önceki header ve payload bilgisinin encode edilmiş hali ve secret kullanılarak imzalanmış yapıdan oluşan bir JWT aşağıdaki şekilde gösterilmektedir:

JWT ile denemeler yapmak için jwt.io‘yu ziyaret edebilir ve bu konseptleri pratiğe dökebilirsiniz. jwt.io üzerinden JWT oluşturabilir, çözümleyebilir, doğrulayabilirsiniz.

JWT nasıl çalışıyor?

Kimliklendirme işlemlerinde, kullanıcı kendi kimlik bilgileriyle başarılı bir şekilde giriş yaptığında, geleneksel bir yaklaşım olan sunucu tarafında session açılıp kulanıcıya cookie dönülmesi yerine, geriye bir JWT döndürülür ve tekrar kullanılmak üzere localStorage veya cookies gibi yapılarda JWT saklanır.

Kullanıcı korunmuş bir kaynağa erişmek istediğinde, istemci tarafından Authorization başlığı içerisinde Bearer şeması kullanılarak JWT sunucuya iletilmelidir. Oluşturulan HTTP başlığı içeriği aşağıdaki gibi olmalıdır:

Authorization: Bearer <token>

Buradaki stateless (durumsuz) kimliklendirme mekanizması sayesinde session’da yapılanın aksine kullanıcının durum bilgisi asla sunucunun hafızasında (RAM’inde) saklanmamış olur. Sunucudaki korunan kaynağa erişim izni Authorization başlığındaki JWT’nin geçerliliği ile kontrol edilir. Eğer geçerli ise, kullanıcının korunan kaynağa erişim izni sağlananır. JWT’ler kendi kendini betimledikleri için, bütün gerekli bilgi JWT’nin içerisindedir. Bu sayede veritabanı üzerinden kimlik doğrulama için çoklu sorgu işlemleri yapılmasının önüne geçilmiş olur.

Aşağıdaki diyagramda JWT’nin işleyişi yer almaktadır:

Neden JWT kullanmalısınız?

Simple Web Tokens (SWT) ve Security Assertion Markup Language Tokens (SAML) ile kıyasla JSON Web Tokens (JWT)‘ın neden daha iyi olduğuna değinelim.

JSON içeriğinin XML’e göre daha yalın olması sebebiyle, base64 ile kodlandığında daha küçük bir hale gelen JWT, SAML’den daha kompakt olmaktadır. Bu sayede, HTML ve HTTP ortamlarında JWT kullanımı daha iyi bir seçim haline gelmektedir.

SWT, HMAC algoritması kullanılarak ortak bir gizli anahtar ile sadece simetrik olarak şifrelemeye izin vermektedir. Oysa ki, JWT ve SAML standartları imzalama için X.509 sertifikasını oluşturacak şekilde açık/gizli anahtar ikililerini kullanabilirler. Fakat SAML’da arkanızda güvenlik açığı bırakmayacak şekilde XML imzalama işlemi JSON imzalamaya göre çok daha zor gerçekleştirilir.

JSON parser’lar, direkt olarak nesnelere dönüşüm işlemini gerçekleştirebildiği için birçok programlama dilinde yaygın olarak kullanılıyor. XML cephesinde ise doğal yollarla bir XML dokümanının nesneye dönüştürülmesi için bir yöntem bulunmamakta. Bu nedenle JWT ile çalışmak, SAML ile çalışmaya göre çok daha kolaylık sağlıyor.

Kullanımı baz alacak olursak, JWT bütün bir internet ölçeğinde kullanılmaktadır. Üstte bahsedilen konular da, başta mobil olmak üzere internete bağlı birçok platforma yönelik istemci taraflı JWT token’larının işlenme sürecinde kolaylıklarını ele almaktadır.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir