JWT(JSON Web Tokens) Nedir? Nasıl Çalışır? #1

Tuğrul Bayrak
4 min readMar 23, 2019

--

Web projelerimizi geliştirirken kullanıcı kimliklendirme/yetkilendirme işlemi oldukça önemlidir. Uygulamamızı yetkisiz kişilerden korumak ve yalnızca yetkili kullanıcıların erişimi için çeşitli yöntemler kullanırız. Bu çözümlerden birisi de token kullanmaktır. İşte bu noktada çeşitli standartlar bulunmaktadır. Bu yazımızda da JWT ile Authorization işlemine bakacağız. Burada Authentication ile karıştırılmamalı. Authentication, kimlik doğrulamadır. Authorization ise sisteme giriş için yetki kontrolüdür. Authentication birkez yapıldıktan sonra, atılan her istekte bir authorization işlemi yapılır. Tabi bu durum geliştirdiğiniz uygulamaya göre değişebilir.

JWT (JSON Web Tokens) Nedir? 🖥

JWT(JSON Web Tokens), bir RFC7519 endüstri standartıdır. JWT, kullanıcının doğrulanması, web servis güvenliği, bilgi güvenliği gibi birçok konuda kullanılabilir. JWT oldukça popüler ve tercih edilen bir yöntemdir. Önce JWT kullanırken ki senaryodan, daha sonra JWT’nin token oluşturma ve verify gibi kısımlarından, son olarakta avantajlarından ve dezavantajlarından bahsedeceğiz.

Senaryomuz

1- Client(İstemci), login sayfasında kullanıcı adı(veya mail) ve parola ile sunucu tarafına bir login isteği gönderir.

2- Sunucu gelen bilgiyi veritabanı sorgusu ile kontrol eder. Eğer geçersizse authentication error ‘401 Unauthorized’ döner, geçerliyse kullanıcı bilgileri ve önceden belirlenmiş bir gizli anahtar ile token oluşturur. Bu token client tarafına HTTP isteğinin ‘Header’ kısmında gönderir. (Ayrıca oluşturulan token veritabanında ilgili kullanıcı adına kaydedilebilir ama JWT’nin çalışmasını etkilemez.)

3- Client(İstemci) gelen token bilgisini local depolama(localStorage gibi) alanında tutar. Daha sonra yetki isteyen tüm isteklerde(get, post, put, delete…) Header bilgisi içerisinde bu token bilgisini gönderir. Gelen her istekte sunucu tokenı kontrol eder(verify) ve kullanıcının erişip erişemeyeceğini denetler. Erişim kabul edilirse normal şekilde veri akışı devam eder. Kabul etmezse client tarafına ‘403 Forbidden’ döner.

Authorization için senaryomuz özetle bu şekilde. Tabi burada tokenın oluşturulması, verify edilmesi, HTTP isteği içerisinde bunun gönderilmesi gibi ince detaylar da var. Hepsine bakacağız.

JWT(JSON Web Tokens) Yapısı

JWT ile üretilen token Base64 ile kodlanmış 3 ana kısımdan oluşmaktadır. Bunlar Header(Başlık), Payload(Veri), Signature(İmza) kısımlarıdır. Bu kısımlara daha yakından bakalım. Aşağıdaki token örneğinde dikkat edecek olursak aaa.bbb.ccc şeklinde noktalarla ayrılmış 3 alan bulunmaktadır.

Örnek JWT Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdGF0dXMiOiJ0ZWJyaWtsZXIhIDopIn0.sTLXY5iAs1IzJJ-8GVP_pMR65qqgCUpbMl-aSPcrQHc

Header(Başlık)

JWT’de kullanılacak bu kısım JSON formatında yazılmakta ve 2 alandan oluşmaktadır. Bunlar token tipi ve imzalama için kullanılacak algoritmanın adı. Örnek olarak:

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

Algoritma kısmında HS256, HMAC SHA256 ya da RSA gibi birçok farklı algoritma kullanılabilir. Type kısmında ise JWT yazmakta. Bu kısım Base64 ile encode edilir ve oluşturulacak tokenın ilk parçasını oluşturur.

Payload(Veri) 📁

Bu kısım ‘claim’leri içerir. Bu kısımda tutulan veriler ile token istemci ve sunucu arasında eşsiz olur. Bu tutulan claim bilgileri de bu eşsizliği sağlar. Bu kısımda 3 tip claim bulunmaktadır.

Registered(Kayıtlı) claims: JWT tarafından önceden reserve edilmiş 3 harf uzunluğunda claimlerdir. Yani bu ayarlanmış belli claim isimlerini diğer claimlerde kullanamazsınız. Bu bilgilerin kullanılması zorunlu değildir ama önerilmektedir. Bu claimlerden bazıları iss (issuer), exp (expiration time), sub (subject), aud(audience) ve diğerleri. Bunlardan en çok kullanılanı expiration time yani son geçerlilik tarihidir. Örneğin token bilginizin 3 saat sonra geçersiz olmasını isterseniz bu bilgiyi exp alanında gönderirsiniz. 3 saat ardından aynı token ile gelen isteklerde token geçersiz olarak değerlendirilir.

Public (Açık) claims: İsteğe bağlı, açık yayınlanan claimlerdir.

Private (Gizli) claims: Tarafların kendi aralarında bilgi taşımak için kullandığı gizli claimlerdir.

Örnek bir payload alanı:

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}

Bu kısım Base64 ile encode edilir ve oluşturulacak tokenın ikinci parçasını oluşturur.

Signature(İmza) 🔐

Bu kısım tokenın son kısmıdır. Bu kısmın oluşturulabilmesi için header, payload ve gizli anahtar(secret) gereklidir. İmza kısmı ile veri bütünlüğü garanti altına alınır. Burada kullandığımız gizli anahtar Header kısmında belirttiğimiz algoritma için kullanılır. Header ve Payload kısımları bu gizli anahtar ile imzalanır

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)

JWT Verify(Doğrulama) 🔓

Doğrulama işlemi üstteki senaryoda da belirttiğimiz gibi client tarafından token geldikten sonra kullanıcının yetkisini kontrol etmek için kullanılır. Tokenın geçerli olup olmadığı JWT ile doğrulanır. JWT doğrulama işlemi oldukça basittir. Gelen tokenda Header(1. kısım) ve Payload(2. kısım) sunucumuzda bulunan gizli anahtar ile imzalanır ve 3. kısım hesaplanır. Daha sonra bu oluşturulan imza(3. kısım) client tarafından gelen imza ile karşılaştırılır. Eğer imzalar aynı ise token geçerli sayılır ve kullanıcıya erişim verilir.

JWT(JSON Web Tokens) Avantajları

1- Stateless çalışır. Yani kontrol edecek bir Session bulunmamaktadır. Bilgiler ve son geçerlilik tarihi ne sunucuda ne client tarafında tutulur. Token içerisinde gerekli bilgiler tutulur.

2- Portable çalışır. Birden çok backend ile çalışabilir, yalnızca 2 taraf arasında kullanılmak zorunda değildir. Bu durum hem web uygulamanız hem de mobil uygulamanız aynı web servisi kullandığında oldukça önemlidir.

3- JSON formatını kullanır.

4- Doğrulama işlemi diğer Authorization metodlarına göre daha hızlıdır. Doğrulama işlemi için veritabanı ile bağlantı kurmaya gerek kalmaz.

5- Cookie kullanmaya gerek yoktur. Mobil uygulamalar için de rahatlıkla kullanılabilir.

JWT’nin ne olduğuna, nasıl çalıştığına ve avantajlarına baktık. Yazı biraz uzun olduğu için bunun NodeJS üzerinde Express REST API için örneklemesini sonraki yazıya bırakacağım. Görüşmek üzere.

--

--