Modern web uygulamalarında güvenliği sağlamak her zamankinden daha önemlidir. Kimlik doğrulama, bu güvenliğin temel taşlarından biridir. Bu yazıda, JWT tabanlı kimlik doğrulama sisteminin nasıl çalıştığını ele alacağız.
JWT Nedir?
JWT (JSON Web Token), web uygulamaları ve servisleri arasında güvenli bilgi alışverişini sağlamak amacıyla oluşturulan, kompakt ve kendi kendine yeten bir token formatıdır.
JWT’nin popülerliği, onun hem kolay entegre edilebilir olmasından hem de güvenli veri transferi sağlamasından kaynaklanmaktadır. JSON formatındaki bu token’lar, istemci ve sunucu arasında gönderilebilir ve sunucu tarafında doğrulanabilir.
Token
Token, bir bilgi veya aksiyonu temsil eden, genellikle rastgele üretilen bir dizi karakterdir. Kimlik doğrulama mekanizmalarında, tokenlar bir kullanıcının kimliğini veya oturumunu doğrulamak için kullanılır. Örneğin, bir token şu şekilde olabilir:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT’nin yapısı üç ana bölümden oluşur: Başlık (Header), Yük (Payload) ve İmza (Signature).
- Başlık (Header): Token’ın tipini (genellikle JWT) ve kullanılan imzalama algoritmasını belirtir.
- Yük (Payload): Token içerisinde taşınacak olan bilgileri (claims) içerir. Bu bilgiler genellikle kullanıcı bilgileri, rol bilgileri ve diğer özellikler olabilir.
- İmza (Signature): Bu bölüm, başlık ve yükün bir kombinasyonu ile bir “secret” anahtarının birleştirilip şifrelenmesiyle oluşturulur. İmza, token’ın değiştirilmeden geldiğini doğrulamak için kullanılır.
Header ve payload JSON formatında olduğundan token tipine ismini vermiştir
Şifreleme İşlemi
Şifreleme, bilginin yetkisiz kişiler tarafından okunmasını engellemek amacıyla bir bilgiyi anlaşılmaz bir forma dönüştürme işlemidir. Bu işlemde genellikle bir anahtar kullanılır. Şifrelenen bilgi ancak uygun bir şifre çözme anahtarıyla orijinal haline döndürülebilir. Örneğin, “Merhaba Dünya!” metni şifrelendiğinde Q3J5cHRlZCBUZXh0IQ== gibi bir çıktı elde edilebilir.
JWT Örneği
JWT’nin içerdiği bilgileri URL ve HTTP başlıklarında güvenli bir şekilde taşımak için Base64Url formatında kodlama kullanılır. Başlık:
{
"alg": "HS256",
"typ": "JWT"
}
Base64Url formatında encode edildiğinde:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Yük:
Kullanıcıyı tanımlamak için kullacağımız veriyi ve zaman aşımı tarihini tutabilir.
{
"user_id": 123,
"username": "exampleUser",
"exp": "2023-10-07T16:22:35.994721"
}
Base64Url formatında encode edildiğinde:
eyJ1c2VyX2lkIjoxMjMsInVzZXJuYW1lIjoiZXhhbXBsZVVzZXIiLCJleHAiOiIyMDIzLTEwLTA3VDE2OjIyOjM1Ljk5NDcyMSJ9
İmza: Başlık ve yük Base64Url formatları “.” ile birleştirilir:
eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJ1c2VyX2lkIjoxMjMsInVzZXJuYW1lIjoiZXhhbXBsZVVzZXIiLCJleHAiOiIyMDIzLTEwLTA3VDE2OjIyOjM1Ljk5NDcyMSJ9
Bu değeri, bir “secret” anahtar ile (örn. “mysecretkey”) birlikte HS256 algoritmasını kullanarak şifreleyerek imzayı elde ederiz. İmza:
TNnYpMANsCSCI2BELs-3Y9PdZosbvI2orzVgpgnSDqw
Bunu da sona “.” ile ekleriz ve JWT’yi elde ederiz:
eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJ1c2VyX2lkIjoxMjMsInVzZXJuYW1lIjoiZXhhbXBsZVVzZXIiLCJleHAiOiIyMDIzLTEwLTA3VDE2OjIyOjM1Ljk5NDcyMSJ9.TNnYpMANsCSCI2BELs-3Y9PdZosbvI2orzVgpgnSDqw
PyJwt
Yukarıdaki işlemleri python ile PyJwt kütüphanesini kullanrak aşağıdaki gibi gerçekleştirebiliriz:
import jwt
from datetime import datetime, timedelta
# Anahtar ve algoritma
SECRET_KEY = "mysecretkey"
ALGORITHM = "HS256"
# Başlık ve yük verileri
header = {
"alg": ALGORITHM,
"typ": "JWT"
}
payload = {
"user_id": 123,
"username": "exampleUser",
# Son kullanma tarihi (örneğin, 1 saat sonra)
"exp": datetime.utcnow() + timedelta(hours=1)
}
# JWT oluşturma
encoded_jwt = jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM, headers=header)
JWT’nin Kimlik Doğrulamada Kullanımı
JWT tabanlı kimlik doğrulama, modern web uygulamalarında sıkça kullanılan bir yöntemdir. Temelde, kullanıcının kimlik bilgilerini doğruladıktan sonra, sunucu bu bilgilere dayanarak bir JWT oluşturur ve bunu istemciye gönderir. İstemci bu tokenı alır ve her istekte sunucuya bu tokenı gönderir, böylece sunucu istemcinin kim olduğunu ve ne yapabileceğini doğrular.
JWT’nin Avantajları
- Durumsuzluk (Statelessness): Sunucu, istemcinin durumunu saklamaz. Bunun yerine, her şey JWT içinde kodlanmıştır. Bu, ölçeklendirilebilirliği artırır çünkü sunucular arasında oturum bilgisi paylaşma ihtiyacı yoktur.
- Genişletilebilirlik: JWT, birkaç temel bilgiyle başlarken, gerektiğinde ek bilgiler (claims) ile genişletilebilir. Bu, uygulamanın gereksinimlerine göre özelleştirilebilir bir yapı sağlar.
- Taşınabilirlik: JWT’ler küçük ve URL güvenli formatında oldukları için, HTTP başlıklarında, URL’lerde ve POST verilerinde kolayca taşınabilirler.
JWT Kullanmasaydık?
JWT’nin getirdiği avantajları daha iyi anlamak için, JWT kullanılmadan neler yapılacağını ve bu yaklaşımın hangi sorunlara yol açabileceğini gözden geçirelim:
- Oturum Tabanlı Kimlik Doğrulama: Geleneksel olarak, kullanıcıların kimlik bilgileri sunucu tarafında oturum(session) olarak saklanır. Bu yaklaşım, sunucunun her oturum için bellekte ya da veritabanında saklama yapmasını gerektirir. Bu, özellikle büyük ölçekli uygulamalarda ölçeklendirme sorunlarına yol açabilir.
- Oturum Paylaşımı Sorunları: Birden fazla sunucu kullanıldığında, oturum bilgilerinin tüm sunucular arasında senkronize edilmesi gerekmektedir. Bu, hem karmaşık bir süreçtir hem de performans üzerinde olumsuz etkiler yaratabilir.
Kimlik Doğrulama Akışı
- Kullanıcı Girişi: Kullanıcı, kullanıcı adı ve şifre gibi kimlik bilgileriyle uygulamaya giriş yapar.
- Kimlik Doğrulama: Sunucu, kullanıcının kimlik bilgilerini doğrular. Eğer bilgiler doğruysa, sunucu bir JWT oluşturur.
- Token Gönderimi: Sunucu, oluşturulan JWT’yi istemciye gönderir. İstemci bu tokenı tarayıcının “local storage”, “session storage” veya bir cookie içerisinde saklar.
- Yetkilendirilmiş İstekler: İstemci, sunucuya yapacağı her istekte, HTTP başlığında bu JWT’yi gönderir. Sunucu, token’ı doğrular ve eğer token geçerliyse, istemcinin talebine cevap verir.
- Token Süresi Dolumu: JWT’nin bir süre limiti vardır. Bu süre dolduğunda, token geçersiz hale gelir. İstemcinin yeni bir token alması gerekir.
Güvenlik Önlemleri
- Kısa Süreli Token’lar: Token’ların kısa süreli olması, bir token’ın ele geçirilmesi durumunda bile zararın sınırlı kalmasını sağlar. Eğer token süresi dolmuşsa, istemci yeni bir token almak için tekrar kimlik doğrulama yapmalıdır.
- HTTPS: JWT’ler hassas bilgiler içerebilir, bu nedenle uygulama ile sunucu arasındaki tüm iletişim HTTPS üzerinden yapılmalıdır.
- Token Saklama: JWT’leri tarayıcıda saklarken dikkatli olmalıyız. Çerezlerde saklamak, XSS saldırılarına karşı hassas hale getirebilir. Yerel depolamada saklamak, CSRF saldırılarına karşı risk taşır. Her iki yöntemin de riskleri vardır, bu nedenle kullanım şeklini dikkatlice değerlendirmek gerekir.
JWT’nin Popüler Kullanım Alanları
JWT teknolojisinin sunduğu esneklik, ölçeklendirilebilirlik ve taşınabilirlik sayesinde birçok modern teknoloji ve uygulamada karşımıza çıkmaktadır. İşte JWT’nin popüler olarak kullanıldığı bazı teknolojik alanlar ve platformlar:
- Tek Sayfalı Uygulamalar (SPA): React, Vue.js ve Angular gibi modern frontend kütüphaneleri ve framework’leri, sunucusuz mimarilere veya API tabanlı servislere bağlandığında JWT tabanlı kimlik doğrulamayı sıkça tercih ederler.
- Mobil Uygulamalar: Mobil platformlar, kullanıcının kimliğini doğrulamak ve API servisleriyle güvenli bir şekilde iletişim kurmak için JWT’leri kullanır. Özellikle platformlar arası çalışan uygulamalar için JWT ideal bir seçenektir.
- Mikroservis Mimarileri: Küçük, bağımsız servislerin bir araya gelerek büyük bir uygulama oluşturduğu mikroservis mimarilerinde, servisler arasında güvenli veri alışverişini sağlamak için JWT sıkça kullanılır.
- Bulut Servisleri: AWS, Google Cloud ve Azure gibi büyük bulut hizmet sağlayıcıları, servisler arası kimlik doğrulama ve yetkilendirme için JWT’leri kullanır.
Sonuç
JWT, modern web uygulamalarında kimlik doğrulama ve yetkilendirme için yaygın olarak kullanılan güçlü bir araçtır. Esneklik, ölçeklendirilebilirlik ve taşınabilirlik gibi avantajları sayesinde birçok uygulama ve serviste tercih edilmektedir. Ancak her teknoloji gibi, JWT’nin de kullanımı sırasında dikkat edilmesi gereken bazı önemli hususlar bulunmaktadır. Güvenlik ve performansı optimize etmek için bu hususları göz önünde bulundurarak doğru bir şekilde kullanmak önemlidir.
JWT ile birlikte kullanılan “access” ve “refresh token tipleri, oturum sonlandırma durumunda tokenlerin doğru bir şekilde geçersiz kılınması gibi daha detaylı anlatıma ihtiyaç duyulan konular hakkında bir dahaki yazılarda görüşmek üzere!