Takip et

JSON Web Token (JWT) Nedir ve Neden Önemlidir?

Express.js’te JWT Kullanımı: Güvenli Kimlik Doğrulama Rehberi

Modern web uygulamaları geliştirirken, kullanıcı kimlik doğrulaması ve yetkilendirmesi, uygulamanızın güvenliğinin temelini oluşturur. Peki, sunucu tarafında oturum bilgisi tutmadan, ölçeklenebilir ve güvenli bir kimlik doğrulama sistemi nasıl kurulur? JSON Web Token (JWT) bu soruna şık ve etkili bir çözüm sunar. Bu makalede, Express.js tabanlı uygulamalarınızda JWT’yi adım adım nasıl kullanacağınızı, temel kavramlardan ileri düzey güvenlik stratejilerine kadar tüm detaylarıyla keşfedeceğiz. Artık API’lerinizin güvenliğini sağlamak için hazırsınız.

JSON Web Token (JWT) Nedir ve Neden Önemlidir?

Günümüzün mikroservis tabanlı ve API odaklı mimarilerinde, geleneksel oturum tabanlı kimlik doğrulama yöntemleri genellikle yetersiz kalmaktadır. Her isteğin durum bilgisini (state) sunucuda tutmak, özellikle yatay ölçeklenebilirlik (horizontal scaling) söz konusu olduğunda ciddi performans ve yönetim zorluklarına yol açar. İşte tam bu noktada, JSON Web Token (JWT) devreye girerek, sunucuda herhangi bir oturum bilgisi tutulmasına gerek kalmadan, istemci ile sunucu arasında güvenli ve doğrulanabilir bilgi alışverişini sağlayan bir standart sunar.

JWT, temel olarak üç ana bölümden oluşur: Başlık (Header), Yük (Payload) ve İmza (Signature). Bu üç bölüm, birer nokta (.) ile birleştirilerek tek bir dize (string) halinde temsil edilir. Başlık kısmı, token’ın türünü (genellikle “JWT”) ve kullanılan şifreleme algoritmasını (örneğin, HS256 veya RS256) içerir. Yük kısmı ise, token’ın kimin hakkında olduğunu, ne zaman oluşturulduğunu, ne zaman sona ereceğini ve kullanıcıya özel diğer verileri (örneğin, kullanıcı ID’si, rolleri) barındırır. Bu bilgilere “claim” adı verilir ve standart (registered claims), genel (public claims) veya özel (private claims) olabilirler. Son olarak, İmza kısmı, token’ın bütünlüğünü ve orijinalliğini garanti eder. Başlık ve Yük kısımları base64url ile kodlandıktan sonra, sunucuda sadece sizin bildiğiniz gizli bir anahtar (secret key) kullanılarak şifrelenir. Bu, token’ın içeriğinin değiştirilmediğinden emin olmamızı sağlar. Eğer token’ın herhangi bir kısmı değiştirilirse, imza geçersiz hale gelir ve sunucu token’ı reddeder.

JWT’nin en büyük avantajlarından biri “stateless” (durum bilgisi tutmayan) yapısıdır. Sunucu, her istekte gelen JWT’yi doğrulayarak kullanıcının kimliğini ve yetkilerini anında anlayabilir. Bu, sunucunun belleğinde oturum bilgisi tutma yükünü ortadan kaldırır, dolayısıyla uygulamanızın daha kolay ölçeklenmesine olanak tanır. Bir kullanıcı giriş yaptığında, sunucu bir JWT oluşturur ve istemciye geri gönderir. İstemci, bu token’ı sonraki tüm yetkilendirme gerektiren isteklerde “Authorization” başlığında (genellikle “Bearer” şemasıyla) sunucuya geri gönderir. Sunucu ise her istekte bu token’ı doğrulayarak kullanıcının kimliğini tespit eder ve ilgili işlemi gerçekleştirmesine izin verir. Bu yöntem, özellikle mobil uygulamalar, tek sayfalı uygulamalar (SPA’lar) ve mikroservis mimarileri için idealdir, çünkü farklı servisler aynı gizli anahtarı kullanarak token’ları doğrulayabilir ve böylece merkezi bir kimlik doğrulama servisine bağımlılığı azaltır. JWT, şifrelenmiş olmasa da (sadece kodlanmıştır), imza sayesinde içeriğinin değiştirilemez olmasıyla önemli bir güvenlik katmanı sunar.

Express.js Projesinde JWT Entegrasyonu Nasıl Yapılır?

Express.js uygulamanıza JWT entegrasyonu yapmak, birkaç temel adımda gerçekleştirilebilir. Bu süreç, bir kullanıcının sisteme kaydolması veya giriş yapmasıyla başlar, ardından sunucunun bir JWT oluşturup istemciye göndermesiyle devam eder. İstemci, aldığı bu token’ı sonraki tüm yetkilendirilmiş isteklere ekleyerek sunucuya geri gönderir. Şimdi, bu adımları detaylı bir şekilde inceleyelim ve gerekli kod örneklerini görelim.

Öncelikle, projemizi oluşturalım ve gerekli paketleri kuralım. Bir Node.js projesi başlatmak için terminalinizde şu komutları çalıştırın:


npm init -y
npm install express jsonwebtoken dotenv bcryptjs
    

express web çerçevesi, jsonwebtoken JWT oluşturma ve doğrulama kütüphanesi, dotenv çevre değişkenlerini yönetmek için ve bcryptjs ise şifreleri güvenli bir şekilde hashlemek için kullanılacaktır.

Kullanıcı Kayıt ve Giriş Akışı

Kullanıcıların sisteme güvenli bir şekilde kaydolması ve giriş yapması, JWT tabanlı kimlik doğrulamanın ilk adımıdır. Kayıt işlemi sırasında kullanıcı şifreleri asla düz metin olarak veritabanına kaydedilmemeli, bunun yerine güçlü bir hash algoritması ile şifrelenmelidir. Bcrypt bu işlem için oldukça popüler ve güvenli bir seçimdir. Giriş işlemi sırasında ise, kullanıcının girdiği şifre, veritabanındaki hash ile karşılaştırılır.

Aşağıdaki örnek kod bloğu, basit bir kullanıcı modeli, kayıt ve giriş rotalarını göstermektedir. Bu örnekte veritabanı olarak basit bir dizi kullanacağız, ancak gerçek bir uygulamada MongoDB, PostgreSQL gibi bir veritabanı kullanmanız gerekecektir.


// app.js
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
require('dotenv').config(); // .env dosyasındaki değişkenleri yükler

const app = express();
app.use(express.json()); // Body'deki JSON verilerini parse etmek için

const users = []; // Gerçek uygulamada burası bir veritabanı olacaktır

// JWT gizli anahtarı (güvenli bir yerde saklanmalı!)
const JWT_SECRET = process.env.JWT_SECRET || 'supersecretjwtkey';

// Kullanıcı Kayıt Rotası
app.post('/register', async (req, res) => {
    try {
        const { username, password } = req.body;

        // Kullanıcı adı kontrolü
        if (users.some(user => user.username === username)) {
            return res.status(400).send('Bu kullanıcı adı zaten mevcut.');
        }

        // Şifreyi hashleme
        const hashedPassword = await bcrypt.hash(password, 10); // 10 salt rounds

        const newUser = { id: users.length + 1, username, password: hashedPassword, roles: ['user'] };
        users.push(newUser);

        res.status(201).send('Kullanıcı başarıyla kaydedildi.');
    } catch (error) {
        console.error(error);
        res.status(500).send('Sunucu hatası.');
    }
});

// Kullanıcı Giriş Rotası
app.post('/login', async (req, res) => {
    try {
        const { username, password } = req.body;

        // Kullanıcıyı bul
        const user = users.find(u => u.username === username);
        if (!user) {
            return res.status(400).send('Kullanıcı adı veya şifre yanlış.');
        }

        // Şifreleri karşılaştır
        const isMatch = await bcrypt.compare(password, user.password);
        if (!isMatch) {
            return res.status(400).send('Kullanıcı adı veya şifre yanlış.');
        }

        // JWT oluşturma
        const token = jwt.sign(
            { id: user.id, username: user.username, roles: user.roles },
            JWT_SECRET,
            { expiresIn: '1h' } // Token 1 saat sonra sona erecek
        );

        res.json({ token });
    } catch (error) {
        console.error(error);
        res.status(500).send('Sunucu hatası.');
    }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(Sunucu ${PORT} portunda çalışıyor.);
});
    

Yukarıdaki kodda, /register rotası yeni bir kullanıcı oluştururken şifreyi hashler. /login rotası ise kullanıcının kimlik bilgilerini doğruladıktan sonra jwt.sign() metodunu kullanarak bir JWT oluşturur. Bu token, kullanıcının ID’si, kullanıcı adı ve rolleri gibi bilgileri içerir ve 1 saat geçerlilik süresine sahiptir. Oluşturulan token, istemciye JSON yanıtı olarak geri gönderilir.

Uzman İpucu: .env dosyanızı versiyon kontrol sistemlerine (Git gibi) asla yüklemeyin. .gitignore dosyanıza .env ekleyerek gizli anahtarlarınızın güvende kalmasını sağlayın.

JWT ile Kimlik Doğrulama ve Yetkilendirme Mekanizması

JWT’nin en güçlü yönlerinden biri, bir kez oluşturulduktan sonra, sunucunun her isteği ayrı ayrı doğrulamak için kullanabileceği bir “pasaport” görevi görmesidir. İstemci, giriş yaptıktan sonra aldığı token’ı sonraki tüm yetkilendirme gerektiren API isteklerinde sunucuya geri göndermelidir. Sunucu tarafında ise bu token’ın geçerliliğini kontrol eden ve kullanıcı bilgilerini istek objesine ekleyen bir ara katman (middleware) fonksiyonu oluşturulur. Bu middleware, Express.js uygulamalarında kimlik doğrulama ve yetkilendirme süreçlerinin merkezi bir parçasıdır.

Doğrulama Middleware’i Yazımı

Bir JWT doğrulama middleware’i, gelen her isteğin “Authorization” başlığını kontrol eder. Eğer bu başlıkta geçerli bir JWT varsa, token’ı çözer (verify) ve içerdiği kullanıcı bilgilerini (örneğin, kullanıcı ID’si, rolleri) req.user gibi bir objeye ekleyerek bir sonraki işleyiciye aktarır. Eğer token yoksa veya geçersizse, isteği uygun bir hata koduyla reddeder. Bu yapı, kod tekrarını önler ve uygulamanızın güvenliğini merkezi bir noktadan yönetmenizi sağlar.


// authMiddleware.js
const jwt = require('jsonwebtoken');
require('dotenv').config();

const JWT_SECRET = process.env.JWT_SECRET || 'supersecretjwtkey';

const authenticateToken = (req, res, next) => {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // "Bearer TOKEN" kısmından TOKEN'ı al

    if (token == null) {
        return res.status(401).send('Erişim reddedildi: Token sağlanmadı.'); // Token yok
    }

    jwt.verify(token, JWT_SECRET, (err, user) => {
        if (err) {
            console.error('JWT doğrulama hatası:', err);
            return res.status(403).send('Erişim reddedildi: Geçersiz token.'); // Token geçersiz
        }
        req.user = user; // Token'dan çözülen kullanıcı bilgilerini req objesine ekle
        next(); // Bir sonraki middleware veya route handler'a geç
    });
};

module.exports = authenticateToken;
    

Bu middleware, authMiddleware.js adında ayrı bir dosyada tanımlanabilir. Daha sonra, korumak istediğiniz rotalara bu middleware’i ekleyebilirsiniz. Örneğin, sadece giriş yapmış kullanıcıların erişebileceği bir “profil” rotası oluşturalım:


// app.js (devamı)
const authenticateToken = require('./authMiddleware');

// Korumalı rota örneği
app.get('/profile', authenticateToken, (req, res) => {
    res.json({ message: Hoş geldin, ${req.user.username}!, user: req.user });
});
    

Bu örnekte, /profile rotasına yapılan bir istek önce authenticateToken middleware’inden geçer. Eğer token geçerliyse, req.user objesi doldurulur ve istek rotanın işleyicisine ulaşır. Aksi takdirde, middleware isteği 401 veya 403 hata koduyla sonlandırır.

Kullanıcı Rollerine Göre Yetkilendirme

Kimlik doğrulama, kullanıcının kim olduğunu belirlerken; yetkilendirme, kullanıcının belirli bir kaynağa veya işleme erişip erişemeyeceğini belirler. JWT’nin “payload” kısmına kullanıcı rolleri gibi yetkilendirme bilgilerini ekleyerek, çok esnek bir yetkilendirme sistemi oluşturabiliriz. Örneğin, sadece “admin” rolüne sahip kullanıcıların erişebileceği bir rota tanımlayalım:


// authMiddleware.js (devamı)

const authorizeRoles = (roles) => {
    return (req, res, next) => {
        if (!req.user || !req.user.roles) {
            return res.status(403).send('Erişim reddedildi: Rol bilgisi eksik.');
        }
        const hasPermission = roles.some(role => req.user.roles.includes(role));
        if (hasPermission) {
            next();
        } else {
            res.status(403).send('Erişim reddedildi: Yetersiz yetki.');
        }
    };
};

// authMiddleware.js dosyasının sonuna ekleyin
module.exports = { authenticateToken, authorizeRoles };
    

Ve bunu app.js dosyasında kullanalım:


// app.js (devamı)
const { authenticateToken, authorizeRoles } = require('./authMiddleware');

// Sadece adminlerin erişebileceği bir rota
app.get('/admin-dashboard', authenticateToken, authorizeRoles(['admin']), (req, res) => {
    res.json({ message: Admin paneline hoş geldin, ${req.user.username}! });
});

// Hem adminlerin hem de editörlerin erişebileceği bir rota
app.get('/manage-content', authenticateToken, authorizeRoles(['admin', 'editor']), (req, res) => {
    res.json({ message: İçerik yönetimine hoş geldin, ${req.user.username}! });
});
    

Bu authorizeRoles middleware’i, bir dizi rol alır ve isteği yapan kullanıcının (req.user içindeki) bu rollerden en az birine sahip olup olmadığını kontrol eder. Eğer kullanıcı gerekli role sahipse, istek bir sonraki adıma geçer; aksi takdirde 403 (Forbidden) hatası döndürülür. Bu yapı, uygulamanızdaki farklı kullanıcı tipleri için granular yetkilendirme sağlamanıza olanak tanır.

Gerçek Dünya Senaryosu: Bir E-Ticaret API’sinde JWT Kullanımı

Bir e-ticaret uygulamasında JWT kullanımı, hem kullanıcı deneyimini iyileştirir hem de API güvenliğini artırır. Diyelim ki bir e-ticaret API’miz var ve bu API’de ürünleri listeleme, sepete ürün ekleme ve sipariş verme gibi işlevler bulunuyor. Bu senaryoda JWT’yi nasıl entegre edeceğimizi inceleyelim.

Öncelikle, tüm kullanıcıların ürünleri listeleyebilmesi gerektiğini, ancak sepete ürün eklemek veya sipariş vermek için giriş yapmış olmaları gerektiğini varsayalım. Ayrıca, sadece “admin” rolüne sahip kullanıcıların ürün ekleyebilmesi veya mevcut ürünleri düzenleyebilmesi gerektiğini düşünelim.


// app.js (E-Ticaret Senaryosu)
const express = require('express');
const app = express();
const { authenticateToken, authorizeRoles } = require('./authMiddleware'); // Middleware'lerimizi dahil ettik

app.use(express.json());

// Basit bir ürün listesi (gerçekte veritabanından gelir)
let products = [
    { id: 1, name: 'Laptop', price: 1200 },
    { id: 2, name: 'Mouse', price: 25 },
    { id: 3, name: 'Keyboard', price: 75 }
];

// 1. Ürünleri Listeleme (Herkese Açık Rota)
app.get('/api/products', (req, res) => {
    res.json(products);
});

// 2. Sepete Ürün Ekleme (Giriş Yapmış Kullanıcılar)
app.post('/api/cart/add', authenticateToken, (req, res) => {
    const { productId, quantity } = req.body;
    const product = products.find(p => p.id === productId);

    if (!product) {
        return res.status(404).send('Ürün bulunamadı.');
    }

    // Gerçek uygulamada, kullanıcının sepetine ekleme işlemi burada yapılır.
    // req.user.id ile kullanıcının kimliğini alabiliriz.
    console.log(${req.user.username} (ID: ${req.user.id}) sepete ${product.name} ürününden ${quantity} adet ekledi.);
    res.status(200).send(${product.name} sepete eklendi.);
});

// 3. Sipariş Verme (Giriş Yapmış Kullanıcılar)
app.post('/api/orders', authenticateToken, (req, res) => {
    // req.body'den sipariş detaylarını al
    const orderDetails = req.body;
    // Gerçek uygulamada, sipariş veritabanına kaydedilir.
    console.log(${req.user.username} (ID: ${req.user.id}) yeni bir sipariş oluşturdu:, orderDetails);
    res.status(201).send('Siparişiniz başarıyla alındı.');
});

// 4. Yeni Ürün Ekleme (Sadece Adminler)
app.post('/api/products', authenticateToken, authorizeRoles(['admin']), (req, res) => {
    const { name, price } = req.body;
    const newProduct = { id: products.length + 1, name, price };
    products.push(newProduct);
    res.status(201).json(newProduct);
});

// 5. Ürün Güncelleme (Sadece Adminler)
app.put('/api/products/:id', authenticateToken, authorizeRoles(['admin']), (req, res) => {
    const productId = parseInt(req.params.id);
    const { name, price } = req.body;

    const productIndex = products.findIndex(p => p.id === productId);
    if (productIndex === -1) {
        return res.status(404).send('Ürün bulunamadı.');
    }

    products[productIndex] = { ...products[productIndex], name, price };
    res.json(products[productIndex]);
});

// ... diğer rotalar ve sunucu başlatma kodu ...
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(E-Ticaret API'si ${PORT} portunda çalışıyor.);
});
    

Bu senaryoda, /api/products rotası herkese açıktır ve herhangi bir kimlik doğrulaması gerektirmez. Ancak, /api/cart/add ve /api/orders gibi rotalar authenticateToken middleware’i ile korunmaktadır, yani bu işlemleri yapmak için geçerli bir JWT’ye sahip olmak zorunludur. Dahası, /api/products (POST) ve /api/products/:id (PUT) gibi ürün ekleme ve güncelleme rotaları, hem authenticateToken hem de authorizeRoles(['admin']) middleware’lerini kullanarak sadece yönetici rolüne sahip kullanıcıların erişimine izin verir. Bu, e-ticaret platformunuzun farklı kullanıcı yetki seviyelerini güvenli ve esnek bir şekilde yönetmesini sağlar. İstemci tarafında, kullanıcı giriş yaptıktan sonra aldığı JWT’yi her istekte “Authorization: Bearer [token]” başlığıyla göndermelidir.

JWT Güvenliğini Artırma ve Sıkça Yapılan Hatalardan Kaçınma

JWT’ler, sundukları ölçeklenebilirlik ve esneklikle modern uygulamalar için harika bir kimlik doğrulama çözümü olsa da, yanlış kullanıldıklarında ciddi güvenlik açıklarına yol açabilirler. Güvenliği en üst düzeye çıkarmak ve yaygın hatalardan kaçınmak için dikkat etmeniz gereken bazı önemli noktalar bulunmaktadır.

Refresh Token Mekanizması

Erişim token’larının (access token) süresi genellikle kısa tutulur (örneğin, 15 dakika ila 1 saat). Bu, token çalınsa bile saldırganın sınırlı bir süreye sahip olmasını sağlar. Ancak, her kısa sürede kullanıcıdan tekrar giriş yapmasını istemek kötü bir kullanıcı deneyimi yaratır. Bu sorunu çözmek için “Refresh Token” mekanizması kullanılır.

Refresh token’lar, erişim token’larından daha uzun ömürlüdür (örneğin, günler veya haftalar). Kullanıcı giriş yaptığında, hem kısa ömürlü bir erişim token’ı hem de uzun ömürlü bir refresh token’ı alır. Erişim token’ı sona erdiğinde, istemci refresh token’ı kullanarak sunucudan yeni bir erişim token’ı talep eder. Refresh token’lar genellikle veritabanında saklanır ve tek kullanımlık veya belli bir süre sonra geçersiz kılınabilir olacak şekilde tasarlanır. Bu sayede, bir refresh token çalınsa bile, sunucu tarafından kolayca iptal edilebilir ve sistemin güvenliği korunmuş olur.

Uzman İpucu: Refresh token’ları HTTP-only çerezlerde saklayarak XSS (Cross-Site Scripting) saldırılarına karşı daha dirençli hale getirebilirsiniz. Erişim token’ını ise JavaScript ile erişilebilecek bir yerde (örneğin, Local Storage) saklayıp her API isteğinde “Authorization” başlığına ekleyebilirsiniz.

Token Süreleri (Expiration) ve Güvenli Saklama Yöntemleri

JWT’lerin son kullanma süreleri (exp claim), güvenlik açısından kritik öneme sahiptir. Erişim token’ları için kısa süreler (15-60 dakika) tercih edilmelidir. Refresh token’ları için ise daha uzun süreler (günler, haftalar) kullanılabilir, ancak bunlar da gerektiğinde iptal edilebilecek şekilde tasarlanmalıdır. Token’ların güvenli bir şekilde saklanması da hayati önem taşır:

  • HTTP-only Cookies: Refresh token’ları saklamak için idealdir. JavaScript tarafından erişilemezler, bu da XSS saldırılarına karşı koruma sağlar. Secure bayrağı ile sadece HTTPS üzerinden gönderilmelerini sağlayın.
  • Local Storage vs. Session Storage: Erişim token’ları için kullanılabilir, ancak XSS saldırılarına karşı savunmasızdırlar. Eğer Local Storage kullanılıyorsa, uygulamanızın XSS’e karşı çok iyi korunmuş olduğundan emin olun.
  • Bellek İçi Saklama: SPA’lar ve mobil uygulamalar için, erişim token’ını uygulama belleğinde tutmak, sayfa yenilemede kaybolsa da, en güvenli yöntemlerden biridir.

Token İptali (Revocation) ve Kara Liste

JWT’ler doğaları gereği “stateless” olduklarından, bir kez oluşturulduktan sonra süresi dolana kadar geçerlidirler. Bu, bir kullanıcının şifresini değiştirmesi veya hesabının askıya alınması durumunda bile, mevcut erişim token’larının süresi dolana kadar geçerli kalacağı anlamına gelir. Bu durumu yönetmek için “Kara Liste” (Blacklisting) veya “Beyaz Liste” (Whitelisting) gibi yöntemler kullanılabilir:

  • Kara Liste: İptal edilen token’ları (örneğin, kullanıcı çıkış yaptığında veya şifre değiştirdiğinde) bir veritabanında veya Redis gibi hızlı bir önbellekte saklayın. Her istek geldiğinde, token’ın kara listede olup olmadığını kontrol edin. Kara listedeki token’lar reddedilir.
  • Beyaz Liste: Yalnızca aktif refresh token’larını saklayın. Bir refresh token kullanıldığında, eski token’ı geçersiz kılın ve yeni bir tane oluşturun. Bu, her zaman geçerli olan token’ların bir kaydını tutmanıza olanak tanır.

Kara liste mekanizması, özellikle Redis gibi hızlı veri depolama çözümleriyle etkili bir şekilde uygulanabilir. Token’ın süresi, kara listeye eklenirken Redis’teki yaşam süresi (TTL) olarak ayarlanır, böylece süresi dolan token’lar otomatik olarak temizlenir.

Mobil Uygulamalar ve Tek Sayfalı Uygulamalar (SPA) İçin JWT İpuçları

Mobil uygulamalar ve SPA’lar, JWT kullanımında bazı özel hususlara dikkat etmeyi gerektirir:

  • CORS (Cross-Origin Resource Sharing): Farklı domain’lerden gelen istekleri kabul etmek için Express.js uygulamanızda CORS’u doğru şekilde yapılandırmalısınız. cors npm paketi bu konuda size yardımcı olacaktır.
  • Yerel Depolama (Local Storage) vs. Çerezler (Cookies): SPA’larda erişim token’larını Local Storage’da saklamak yaygın olsa da, XSS saldırılarına karşı daha savunmasızdır. HTTP-only çerezler bu riski azaltır ancak CSRF (Cross-Site Request Forgery) saldırılarına karşı ek önlemler gerektirebilir (örneğin, CSRF token’ları). Mobil uygulamalarda ise token’lar genellikle uygulamanın güvenli depolama alanında saklanır.
  • HTTPS Kullanımı: Her zaman HTTPS kullanın! JWT’ler şifrelenmediği için (sadece imzalanır), token’lar ağ üzerinden düz metin olarak iletilir. HTTPS, bu iletim sırasında token’ın dinlenmesini (eavesdropping) önler.

Mobil uyumluluk için, API’nizin yanıtlarının farklı ekran boyutlarında sorunsuz çalışmasını sağlamak, istemci tarafı uygulamanın sorumluluğundadır. Ancak, genel web geliştirme prensiplerinde, duyarlı tasarımlar için CSS media query’leri kullanılır. Örneğin, bir HTML sayfasında aşağıdaki gibi bir yapı, farklı cihazlar için farklı stiller uygulayabilir:


<!-- index.html -->
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mobil Uyumlu Sayfa</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .container { width: 90%; margin: 0 auto; }

        @media (min-width: 768px) {
            .container { width: 70%; }
        }

        @media (min-width: 1024px) {
            .container { width: 50%; }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Responsive Tasarım Örneği</h1>
        <p>Bu metin, ekran boyutuna göre farklı genişliklerde görünecektir.</p>
    </div>
</body>
</html>
    

Bu, doğrudan JWT ile ilgili olmasa da, modern web uygulamalarının genelinde mobil uyumluluğun nasıl sağlandığına dair bir örnek teşkil eder ve API’nizin tüketildiği istemci tarafında bu tür düşüncelerin önemini vurgular.

Sonuç ve Sıkça Sorulan Sorular

Express.js uygulamalarınızda JSON Web Token (JWT) kullanmak, API’leriniz için güçlü, ölçeklenebilir ve durum bilgisi tutmayan bir kimlik doğrulama ve yetkilendirme çözümü sunar. Bu makalede, JWT’nin temel yapısından başlayarak, Express.js projenize nasıl entegre edeceğinizi, kimlik doğrulama ve yetkilendirme middleware’leri yazmayı ve hatta gerçek dünya senaryolarında nasıl kullanabileceğinizi adım adım ele aldık. Ayrıca, refresh token mekanizmaları, güvenli saklama yöntemleri ve token iptali gibi ileri düzey güvenlik konularına değinerek, uygulamanızın potansiyel güvenlik açıklarına karşı daha dirençli olmasını sağlama yollarını inceledik. Doğru stratejilerle uygulandığında, JWT’ler modern web uygulamalarının omurgasını oluşturan API’ler için vazgeçilmez bir araç haline gelir.

Sıkça Sorulan Sorular

Soru Cevap
JWT’ler şifrelenir mi? Hayır, JWT’ler varsayılan olarak şifrelenmez; sadece Base64url ile kodlanır ve imzalanır. Bu, içeriğinin herkes tarafından okunabileceği anlamına gelir. Bu nedenle hassas bilgileri (örneğin, şifreler) payload’a koymaktan kaçınmalısınız. İmza, içeriğin değiştirilip değiştirilmediğini doğrulamak için kullanılır, gizliliği sağlamak için değil.
Refresh token’lar neden gereklidir? Refresh token’lar, kısa ömürlü erişim token’larının süresi dolduğunda kullanıcının tekrar giriş yapmasına gerek kalmadan yeni bir erişim token’ı almasını sağlar. Bu, hem kullanıcı deneyimini iyileştirir hem de erişim token’larının çalınması durumunda saldırganın erişim süresini kısıtlayarak güvenliği artırır.
JWT’leri Local Storage’da saklamak güvenli midir? Local Storage’da JWT saklamak, XSS (Cross-Site Scripting) saldırılarına karşı savunmasızdır. Kötü niyetli bir JavaScript kodu, Local Storage’daki token’a erişebilir ve onu çalabilir. Daha güvenli bir alternatif, token’ları HTTP-only ve Secure bayraklı çerezlerde saklamaktır, ancak bu da CSRF (Cross-Site Request Forgery) saldırılarına karşı önlemler gerektirir.
JWT’yi nasıl iptal edebilirim (revoke)? JWT’ler “stateless” olduklarından, doğrudan iptal edilemezler. Ancak, bir “kara liste” mekanizması uygulayarak iptal edebilirsiniz. Bu yöntemde, iptal etmek istediğiniz token’ları bir veritabanına veya Redis gibi hızlı bir önbelleğe kaydedersiniz. Her istek geldiğinde, token’ın kara listede olup olmadığını kontrol eder ve listedeyse reddedersiniz.
JWT payload’ına hangi bilgileri koymalıyım? Payload’a, kullanıcının kimliğini ve yetkilendirme için gerekli minimum bilgileri (örneğin, kullanıcı ID’si, rolleri, kullanıcı adı) koymalısınız. Hassas kişisel bilgileri veya çok büyük veri setlerini payload’a koymaktan kaçının, çünkü token boyutu artar ve ağ trafiğini yavaşlatır. Unutmayın, payload şifrelenmediği için herkes tarafından okunabilir.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

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

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.