Menu

Node.js JWT ile Kimlik Doğrulama ve Express Route'ları

JWT, sunucunun login sırasında verdiği ve her istekte kontrol ettiği, üç base64url parçadan oluşan imzalı bir token'dır. Node.js'te onu jose ya da jsonwebtoken paketi ve bir secret key ile imzalar ve doğrularsın.

Bu sayfada çalıştırılabilir editörler var. Düzenle, çalıştır ve sonucu anında gör.

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ğiGizli mi?
HeaderHS256 gibi algoritmaHayır, okunabilir
PayloadClaim'ler: sub (kullanıcı id'si), exp (son geçerlilik), iat (veriliş zamanı), kendi alanlarınHayı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.

Coddy programlama dilleri çizimi

Coddy ile kodlamayı öğren

Başla