14.01.2026

JWT Nedir? 20 Dakikada Güvenli Kimlik Doğrulama

JWT ile modern kimlik doğrulamayı öğrenin: token yapısı, güvenlik riskleri, refresh token akışı ve Node.js örneğiyle adım adım uygulayın.

JWT Nedir? 20 Dakikada Güvenli Kimlik Doğrulama

Meta Description

JWT nedir ve nasıl kullanılır? Access/refresh token akışı, güvenlik ipuçları ve Node.js örneğiyle 20 dakikada uygulayın.

Giriş (Introduction)

Bir API geliştiriyorsunuz, mobil uygulama veya SPA (React/Vue) ile konuşuyor… Peki kullanıcı giriş yaptıktan sonra istekleri nasıl güvenli şekilde yetkilendireceksiniz? “Session mı kullanmalıyım, token mı?” sorusu burada başlar.

JWT (JSON Web Token), modern uygulamalarda kimlik doğrulama ve yetkilendirme için en yaygın yaklaşımlardan biri. Doğru uygulandığında hızlı ve ölçeklenebilir; yanlış uygulandığında ise token çalınması, uzun süreli erişim ve hesap ele geçirme gibi riskler doğurabilir.

Bu yazıda JWT’nin mantığını, access token / refresh token akışını ve gerçek hayatta doğru konfigürasyonla nasıl uygulanacağını adım adım öğreneceksiniz.


JWT Nedir? (Ana Anahtar Kelime)

JWT, sunucu ile istemci arasında taşınan, içinde JSON veri barındıran ve imzalanmış bir token formatıdır. En sık kullanım şekli:

  • Kullanıcı giriş yapar
  • Sunucu bir JWT access token üretir
  • İstemci sonraki isteklerde Authorization: Bearer <token> ile bu token’ı gönderir

Bunu neden yapmalıyım?

  • API’lerde stateless (durumsuz) çalışmayı kolaylaştırır
  • Mikro servis ve ölçeklenebilir mimarilerde pratik bir çözümdür
  • Mobil/SPA gibi istemcilerle uyumludur

Not: JWT tek başına “güvenlik” değildir. Güvenlik, doğru süreler, doğru saklama ve doğru doğrulama ile gelir.


JWT Yapısı: Header, Payload, Signature

JWT genelde şu formattadır:

xxxxx.yyyyy.zzzzz

Bölüm Ne içerir? Örnek
Header Algoritma ve token tipi {"alg":"HS256","typ":"JWT"}
Payload İddialar (claims) {"sub":"123","role":"admin","exp":...}
Signature İmza Header+Payload + secret/private key

Payload’da hangi bilgiler olmalı?

  • Minimal veri: sub (user id), role/scope, exp gibi
  • Kritik kişisel verileri (TC, e-posta, adres vb.) payload’a koymayın

Önemli: JWT payload’u şifreli değildir, sadece base64url ile kodlanır. Yani token’ı gören payload’u okuyabilir.


Access Token vs Refresh Token: Doğru Akış

JWT kullanırken en çok yapılan hata: çok uzun süreli access token üretmek.

Önerilen pratik yaklaşım

  • Access Token: kısa ömür (5–15 dk)
  • Refresh Token: daha uzun ömür (7–30 gün) ve sunucu tarafında kontrol (DB/Redis)

Akış (özet)

  1. Kullanıcı giriş yapar → access + refresh token alır
  2. İstemci API çağrılarında access token kullanır
  3. Access token süresi dolunca /auth/refresh çağrılır
  4. Sunucu refresh token geçerliyse yeni access token üretir

Bunu neden yapmalıyım?

  • Access token çalınsa bile etkisi kısa sürer
  • Refresh token’ı iptal ederek oturumu sunucu tarafında sonlandırabilirsiniz

JWT Güvenliği: En Sık Hatalar ve Önlemler

Aşağıdaki maddeler, Türkiye’de ekiplerin en sık takıldığı gerçek problemlerden.

1) Token’ı localStorage’da saklamak

  • XSS açığında token kolayca çalınır
  • Öneri: Refresh token’ı HttpOnly + Secure cookie ile saklayın

2) alg=none veya yanlış algoritma doğrulaması

  • Kütüphaneyi doğru kullanın, algoritmayı kısıtlayın

3) Çok uzun token süresi

  • 1 yıl geçerli access token = büyük risk

4) Logout çalışmıyor sanmak

JWT stateless olduğu için tek başına “logout” sunucu tarafında token’ı yok etmez.

  • Çözüm: Refresh token’ı server-side listede tutup iptal edin (revocation)

5) Audience/Issuer kontrolü yapmamak

  • iss (issuer) ve aud (audience) doğrulaması kritik olabilir (özellikle çoklu servislerde)

Node.js (Express) ile JWT: Adım Adım Uygulama

Aşağıdaki örnek, pratik bir başlangıç iskeleti sunar. (Prod’da ek sertleştirme gerekir.)

1) Kurulum

npm i express jsonwebtoken cookie-parser bcrypt

2) Token üretimi (access + refresh)

import jwt from "jsonwebtoken";

const ACCESS_TTL = "10m";
const REFRESH_TTL = "14d";

export function signAccessToken(user) {
  return jwt.sign(
    { sub: user.id, role: user.role },
    process.env.JWT_ACCESS_SECRET,
    { expiresIn: ACCESS_TTL, issuer: "my-api", audience: "my-app" }
  );
}

export function signRefreshToken(user) {
  return jwt.sign(
    { sub: user.id, type: "refresh" },
    process.env.JWT_REFRESH_SECRET,
    { expiresIn: REFRESH_TTL, issuer: "my-api", audience: "my-app" }
  );
}

3) Middleware: Access token doğrulama

import jwt from "jsonwebtoken";

export function requireAuth(req, res, next) {
  const header = req.headers.authorization;
  const token = header?.startsWith("Bearer ") ? header.slice(7) : null;

  if (!token) return res.status(401).json({ message: "Token gerekli" });

  try {
    const payload = jwt.verify(token, process.env.JWT_ACCESS_SECRET, {
      issuer: "my-api",
      audience: "my-app",
      algorithms: ["HS256"],
    });

    req.user = { id: payload.sub, role: payload.role };
    next();
  } catch (err) {
    return res.status(401).json({ message: "Geçersiz/expired token" });
  }
}

4) Login endpoint (cookie ile refresh token)

import express from "express";
import cookieParser from "cookie-parser";
import { signAccessToken, signRefreshToken } from "./tokens.js";

const app = express();
app.use(express.json());
app.use(cookieParser());

app.post("/auth/login", async (req, res) => {
  const { email, password } = req.body;

  // Demo: kullanıcı doğrulama kısmı (DB + bcrypt) burada olmalı
  const user = { id: "u_123", role: "admin", email };

  const accessToken = signAccessToken(user);
  const refreshToken = signRefreshToken(user);

  // Öneri: refresh token'ı DB/Redis'te saklayın (rotasyon/revocation için)

  res.cookie("refresh_token", refreshToken, {
    httpOnly: true,
    secure: true,
    sameSite: "strict",
    path: "/auth/refresh",
    maxAge: 14 * 24 * 60 * 60 * 1000,
  });

  res.json({ accessToken });
});

5) Refresh endpoint (yeni access token)

import jwt from "jsonwebtoken";

app.post("/auth/refresh", (req, res) => {
  const token = req.cookies.refresh_token;
  if (!token) return res.status(401).json({ message: "Refresh token yok" });

  try {
    const payload = jwt.verify(token, process.env.JWT_REFRESH_SECRET, {
      issuer: "my-api",
      audience: "my-app",
      algorithms: ["HS256"],
    });

    if (payload.type !== "refresh") {
      return res.status(401).json({ message: "Yanlış token tipi" });
    }

    // Öneri: token DB/Redis'te geçerli mi kontrol edin (revocation)

    const user = { id: payload.sub, role: "admin" }; // DB'den okunmalı
    const newAccessToken = signAccessToken(user);

    res.json({ accessToken: newAccessToken });
  } catch (err) {
    return res.status(401).json({ message: "Refresh token geçersiz/expired" });
  }
});


Gerçek Hayat Senaryosu: SaaS Panelinde JWT Neden Kritik?

Diyelim ki bir SaaS admin paneliniz var:

  • Kullanıcılar gün boyu panelde kalıyor
  • Arka planda onlarca API çağrısı yapılıyor
  • Bir XSS açığı veya cihaz kaybı yaşanabiliyor

Bu senaryoda:

  • Kısa ömürlü access token ile risk daralır
  • HttpOnly cookie ile refresh token’ın çalınması zorlaşır
  • Refresh token rotasyonu + iptal listesi ile hesabı hızlıca güvene alırsınız

Hızlı kontrol listesi

  • Access token 5–15 dk
  • Refresh token HttpOnly+Secure cookie
  • Refresh token server-side saklanıyor (DB/Redis)
  • iss/aud doğrulanıyor
  • Algoritma kısıtlı (ör. HS256)
  • HTTPS zorunlu

JWT Alternatifleri: Ne Zaman JWT Kullanmayayım?

JWT her projeye şart değil.

İhtiyaç Daha uygun seçenek
Klasik web (SSR) ve basit auth Session + server-side store
Kurumsal SSO OAuth2 / OIDC (Keycloak, Auth0 vb.)
Çok servisli yetkilendirme OIDC + kısa ömürlü token + merkezi yetki

Bunu neden bilmeliyim? Yanlış araç seçimi, bakım maliyetini artırır ve güvenliği düşürür.


Sık Sorulan Sorular (FAQ)

1) JWT nedir ve ne işe yarar?

JWT, kullanıcı kimliğini/rollerini taşıyan imzalı bir token formatıdır. API’lerde kimlik doğrulama ve yetkilendirmede kullanılır.

2) JWT güvenli mi?

Doğru süreler, doğru saklama (özellikle refresh token için HttpOnly cookie) ve doğru doğrulama yaparsanız güvenlidir. Payload’un şifreli olmadığını unutmayın.

3) JWT ile logout nasıl yapılır?

Access token stateless olduğu için bekleyip süresinin dolması gerekir. Pratikte refresh token’ı iptal ederek logout uygulanır.

4) Access token süresi kaç olmalı?

Genellikle 5–15 dakika iyi bir dengedir. Daha uzunu risk, daha kısası kullanıcı deneyimi maliyeti doğurur.

5) JWT mi session mı daha iyi?

SPA/mobil + API için JWT pratik olur. SSR ve klasik web uygulamalarında session daha basit ve kontrollü olabilir.


Sonuç

JWT nedir sorusunun cevabı sadece “token” değil; doğru tasarlanmış bir kimlik doğrulama akışı. Bu yazıda JWT yapısını, access/refresh token mantığını, güvenlik hatalarını ve Node.js ile uygulanabilir bir örneği gördünüz.

Siz hangi mimaride JWT kullanıyorsunuz: SPA, mobil, mikro servis? Yorumlarda yazın; kullandığınız akışa göre süre/depoma stratejisi için öneri paylaşabilirim. İsterseniz bir sonraki adım olarak refresh token rotasyonu ve revocation (iptal) modeli için de örnek şablon çıkaralım.