JWT (JSON Web Token), üç base64url parçadan oluşan bir string'dir: header.payload.signature. Sunucu onu login sırasında kullanıcıya verir ve sonraki her istekte kontrol eder. İmza, token'ı sunucunun verdiğini ve kimsenin değiştirmediğini kanıtlar; ama payload şifrelenmemiş, sadece encode edilmiştir, yani herkes okuyabilir. Node.js'te jose paketindeki new SignJWT(payload).sign(secret) ile bir token oluşturur ve jwtVerify(token, secret) ile kontrol edersin.
Program 3 parts, ardından user-42 admin yazdırır: jwtVerify imzayı ve süreyi kontrol edip payload'u döndürdü. jwtVerify'a verilen secret'ın bir karakterini değiştirip tekrar çalıştır: doğrulama signature verification failed ile başarısız olur.
Bir JWT'nin içinde ne var
Header ve payload, base64url ile encode edilmiş JSON'dur. Onları decode etmek için anahtar gerekmez; bir JWT'nin asla parola ya da başka gizli bir şey taşımaması gerekmesinin nedeni budur.
İlk iki satır {"alg":"HS256"} ve {"name":"Ada","role":"editor"} yazdırır; token'ı elinde tutan herkes bunları okuyabilir. Onların token'ı düzenlemesini engelleyen imzadır (HS256 için 43 karakter): editor'ü admin yaparsan imza artık eşleşmez.
| Parça | İçerdiği | Gizli mi? |
|---|---|---|
| Header | HS256 gibi algoritma | Hayır, okunabilir |
| Payload | Claim'ler: sub (kullanıcı id'si), exp (son geçerlilik), iat (veriliş zamanı), kendi alanların | Hayır, okunabilir |
| Signature | İlk iki parçanın HMAC ya da RSA imzası | Oluşturmak için anahtar gerekir |
Süre dolması ve başarısız doğrulama
setExpirationTime('15m') bir exp claim'i yazar ve jwtVerify bu süreyi geçmiş bir token'ı reddeder. Her ret bir code taşıyan bir hatadır, böylece süresi dolmuş bir token'ı sahte olandan ayırt edebilirsin.
İlk kontrol ERR_JWT_EXPIRED ile, imzası değiştirilmiş ikincisi ise ERR_JWS_SIGNATURE_VERIFICATION_FAILED ile başarısız olur. API'n için ikisi de aynı anlama gelir (401 ile cevap ver), ama debug ederken kodu loglamak işe yarar.
Express route'unu Bearer token ile korumak
İstemci bir kez login olur, token'ı saklar ve onu Authorization header'ında Bearer <token> olarak gönderir. Bir middleware token'ı doğrular ve route için payload'u req.user'a koyar.
Token'sız ilk istek, GET /me, 401 ve Missing token alır. {"username": "ada", "password": "lovelace"} body'siyle POST /login gönder, cevaptaki token'ı kopyala, sonra GET /me'yi Authorization: Bearer <token> header'ıyla tekrar gönder: cevap {"id":"user-1","name":"ada"} olur.
jsonwebtoken paketi
jsonwebtoken (npm install jsonwebtoken) diğer yaygın seçenektir. sign ve verify fonksiyonları promise döndürmek yerine senkrondur (isteğe bağlı callback'lerle):
const jwt = require('jsonwebtoken');
const token = jwt.sign({ role: 'admin' }, process.env.JWT_SECRET, {
subject: 'user-42',
expiresIn: '1h',
});
const payload = jwt.verify(token, process.env.JWT_SECRET); // throws if invalid
Yeni kod için jose kullan: hiç bağımlılığı yoktur ve edge runtime'larda ve tarayıcılarda da çalışır. İki kütüphanenin token'ları da standart JWT'dir, yani biri diğerinin imzaladığını doğrulayabilir.
Sık yapılan hatalar
verify yerine decode kullanmak. jwt.decode ve decodeJwt payload'u imzayı kontrol etmeden okur, bu yüzden sahte bir token geçer. Yalnızca verify'ın döndürdüğüne güven.
Kısa ya da commit edilmiş bir secret. Tahmin edilebilir bir HS256 secret'ı saldırganların kendi token'larını imzalamasına izin verir. En az 32 rastgele byte kullan, onu process.env'den oku ve asla commit etme.
Süresi hiç dolmayan token'lar. exp olmadan sızmış bir token sonsuza kadar çalışır. Her zaman bir süre ayarla.
Sıkça Sorulan Sorular
İstemci bir JWT'yi nerede saklamalı?
Bir tarayıcı uygulamasında en güvenlisi HttpOnly, Secure bir cookie'dir, çünkü sayfadaki script'ler onu okuyamaz. localStorage daha basittir, ama sayfadaki herhangi bir script, enjekte edilmiş olanlar dahil, token'ı okuyabilir. Mobil uygulamalar platformun güvenli depolamasını kullanır.
JWT kullanırken bir kullanıcının oturumunu nasıl kapatırım?
Sunucu zaten imzaladığı bir token'ı iptal edemez; token süresi dolana kadar geçerli kalır. İstemcide onu sil, access token'ları kısa ömürlü tut, anında çıkış gerekiyorsa da iptal edilen token id'lerinin (jti) bir listesini sunucuda tut ve her istekte kontrol et.
HS256 mı, RS256 mı?
HS256 imzalama ve doğrulama için tek bir ortak secret kullanır, bu da tek bir backend'e uyar. RS256 private key ile imzalar ve public key ile doğrular, böylece diğer servisler token oluşturamadan onları kontrol edebilir.
Bir JWT ne kadar süre geçerli olmalı?
Access token'lar genellikle 5 ile 60 dakika arası geçerlidir. Daha uzun oturumlar için onları, daha dikkatli saklanan ve istemcinin yeni bir access token'la değiştirdiği bir refresh token ile birlikte kullan.