JavaScript ile JWT Oluşturma: Güvenli Kimlik Doğrulamanın Temelleri

✅ JavaScript ile JWT Oluşturma: Güvenli Kimlik Doğrulamanın Temelleri


🔰 Giriş: JSON Web Token (JWT) Nedir?

JWT (JSON Web Token), web uygulamalarında kullanıcı doğrulama ve bilgi aktarımı için kullanılan açık bir standarttır. Özellikle kullanıcının kimliğini güvenli şekilde doğrulamak, oturum yönetmek ve API güvenliği sağlamak amacıyla tercih edilir.

JWT, üç parçadan oluşan, imzalanmış bir metin dizesidir:

CopyEditeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VybmFtZSI6ImFsaSIsInJvbGUiOiJ1c2VyIn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

📦 JWT Yapısı

JWT üç ana bölümden oluşur:

  1. Header (Başlık): Algoritma ve token türünü belirtir.
  2. Payload (Yük): Kullanıcı bilgileri ve özel veriler bulunur.
  3. Signature (İmza): Header + Payload + Secret Key üzerinden hesaplanır.

🚀 Neden JWT Kullanmalıyız?

  • ✅ Oturum yönetimini stateless (sunucusuz) hale getirir.
  • 🔐 Bilgiler güvenli şekilde iletilir.
  • 🌐 API ve mikro servisler arasında kolay taşınabilir.
  • 🧪 Hızlı doğrulama yapılabilir.

🛠️ JavaScript ile JWT Oluşturma: Uygulamalı Kod Örneği

1. jsonwebtoken Kütüphanesini Kurun

bashCopyEditnpm install jsonwebtoken

2. Basit JWT Oluşturma Örneği

javascriptCopyEditconst jwt = require('jsonwebtoken');

const kullanici = {
  id: 1,
  username: 'ornekKullanici',
  rol: 'admin'
};

const secretKey = 'gizliAnahtar';

const token = jwt.sign(kullanici, secretKey, { expiresIn: '2h' });

console.log("JWT Token:", token);

📌 Açıklama:

  • jwt.sign() fonksiyonu ile token oluşturulur.
  • expiresIn ile geçerlilik süresi ayarlanır.
  • secretKey, sadece sunucu tarafından bilinir.

🔎 JWT Decode Etme (İçeriğini Okuma)

javascriptCopyEditconst decoded = jwt.decode(token);
console.log(decoded);

Bu işlem doğrulama yapmadan sadece payload’ı gösterir. Güvenlik kontrolü için verify() kullanılmalıdır.


🔐 JWT Doğrulama (Verify)

javascriptCopyEdittry {
  const dogrulanmis = jwt.verify(token, secretKey);
  console.log("Doğrulandı:", dogrulanmis);
} catch (err) {
  console.log("Token geçersiz veya süresi dolmuş.");
}

🧱 Express.js API ile JWT Kullanımı

1. Token Üretme Endpoint’i

javascriptCopyEditapp.post('/login', (req, res) => {
  const { username, password } = req.body;

  if (username === 'admin' && password === '1234') {
    const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).json({ mesaj: 'Hatalı giriş!' });
  }
});

2. Korunan Route

javascriptCopyEditfunction tokenKontrol(req, res, next) {
  const token = req.headers['authorization']?.split(' ')[1];

  if (!token) return res.status(403).json({ mesaj: 'Token yok!' });

  jwt.verify(token, secretKey, (err, decoded) => {
    if (err) return res.status(401).json({ mesaj: 'Geçersiz token!' });
    req.kullanici = decoded;
    next();
  });
}

app.get('/gizli', tokenKontrol, (req, res) => {
  res.json({ mesaj: `Hoş geldin ${req.kullanici.username}` });
});

🧠 JWT Kullanım Alanları

AlanAçıklama
🔑 Kimlik DoğrulamaLogin olan kullanıcıya token verilir
🌐 API GüvenliğiHer istekte token doğrulaması yapılır
📱 Mobil UygulamalarBackend ile güvenli iletişim sağlanır
🧩 Mikro servislerServisler arası kimlik doğrulaması
🔒 Role-based accessToken’a rol bilgisi eklenerek yetki kontrolü yapılır

💥 Yaygın JWT Hataları ve Güvenlik İpuçları

⚠️ Hatalar

  • Token’ı istemcide düz metinle saklamak (örneğin localStorage)
  • Süresiz token oluşturmak
  • Secret key’in zayıf olması

✅ Güvenlik İpuçları

  • HTTPS olmadan asla JWT gönderme
  • Token süresi kısa tut
  • Secret key’i güçlü seç
  • Refresh token mekanizması kullan
  • Role & izinleri token içinde tut

📊 JWT ve Cookie / Session Karşılaştırması

ÖzellikJWTSession/Cookie
SaklamaİstemciSunucu (session)
StatikStatelessStateful
HızHızlıGöreceli yavaş
TaşınabilirlikYüksekDüşük
GüvenlikSecret Key gerekliOturum yönetimi

🔁 Refresh Token Kullanımı

🔍 Neden Refresh Token Gerekir?

Access token’lar kısa süreli tutulduğunda (örneğin 15 dakika), kullanıcı deneyimini bozmadan oturumu devam ettirmek için refresh token kullanılır.


🛠 Refresh Token Örneği

1. Giriş (Login) Anında Hem Access Hem Refresh Token Üret:

javascriptCopyEditconst jwt = require('jsonwebtoken');

const kullanici = { id: 1, username: "admin" };

const accessToken = jwt.sign(kullanici, secretKey, { expiresIn: '15m' });
const refreshToken = jwt.sign(kullanici, refreshSecretKey, { expiresIn: '7d' });

res.json({
  accessToken,
  refreshToken
});

2. Refresh Token ile Yeni Access Token Üret:

javascriptCopyEditapp.post('/token', (req, res) => {
  const { refreshToken } = req.body;

  if (!refreshToken) return res.sendStatus(401);

  jwt.verify(refreshToken, refreshSecretKey, (err, user) => {
    if (err) return res.sendStatus(403);

    const yeniAccessToken = jwt.sign({ username: user.username }, secretKey, { expiresIn: '15m' });
    res.json({ accessToken: yeniAccessToken });
  });
});

🧰 JWT İle Yetkilendirme (Authorization)

JWT içerisine kullanıcı rolü eklenerek farklı seviyelerde erişim sağlanabilir.

Kod Örneği:

javascriptCopyEditconst token = jwt.sign({
  id: 5,
  username: 'ali',
  role: 'admin'
}, secretKey, { expiresIn: '1h' });

Yetkilendirme Kontrolü:

javascriptCopyEditapp.get('/admin', tokenKontrol, (req, res) => {
  if (req.kullanici.role !== 'admin') return res.status(403).json({ mesaj: 'Yetkisiz' });
  res.send("Yönetici paneline hoş geldiniz.");
});

⚙️ JWT Saklama Yöntemleri

YöntemAçıklamaGüvenlik
localStorageKolay erişim ama XSS riski yüksek
sessionStorageSekmeye özel, daha güvenli⚠️
HttpOnly CookieJS erişemez, XSS’e karşı korumalı

👉 En güvenli yöntem: HttpOnly ve Secure flag’li cookie kullanımıdır.


📌 JWT Kullanırken Dikkat Edilmesi Gerekenler

  • Token blacklist mekanizması kullan.
  • Uzun süreli refresh token’ları belirli aralıklarla yenile.
  • Token id’si (jti) kullanarak her token’ı benzersiz hale getir.
  • Kullanıcı çıkış yaptığında refresh token’ı sunucudan sil.

🧪 Gerçek Hayatta JWT Kullanım Senaryoları

1. SPA (Single Page Application) Projeleri

Vue, React, Angular gibi frontend frameworkleriyle JWT mükemmel çalışır.

2. Mobil Uygulamalar

Android/iOS uygulamalarında backend ile iletişimde token kullanımı önerilir.

3. Mikroservis Mimarisi

Farklı servislerin birbiriyle iletişiminde merkezi kimlik doğrulama sağlar.


🌍 JWT ile OAuth 2.0 Entegrasyonu

JWT, OAuth 2.0 protokolüyle birlikte kullanılarak sosyal girişlerde (Google, Facebook, GitHub vs.) kullanıcı kimliği taşınabilir hale gelir.

📘 Faydalı Kaynaklar


📚 Eğitim ve Kurs Önerileri

PlatformKursSeviye
Udemy“Node.js REST API with JWT Authentication”Orta
Coursera“Web Security Fundamentals”Başlangıç
YouTubeTraversy Media – JWT Crash CourseOrta
MediumJSON Web Tokens 101 Makale SerisiBaşlangıç-Orta

🚀 Uçtan Uca JWT Kimlik Doğrulama Sistemi

🎯 Hedef

  • Kayıt (register)
  • Giriş (login)
  • Token doğrulama (middleware)
  • Korunan rota (authenticated route)
  • Çıkış (logout)
  • Refresh token sistemi

📁 Proje Yapısı

luaCopyEditjwt-auth/
│
├── controllers/
│   └── authController.js
├── middlewares/
│   └── authMiddleware.js
├── routes/
│   └── authRoutes.js
├── app.js
├── config.js
└── package.json

⚙️ Gerekli Kurulumlar

bashCopyEditnpm init -y
npm install express jsonwebtoken dotenv

.env dosyasına:

envCopyEditACCESS_SECRET=supersecretaccesstoken
REFRESH_SECRET=supersecretrefreshtoken

📄 app.js

javascriptCopyEditconst express = require('express');
const app = express();
const authRoutes = require('./routes/authRoutes');

app.use(express.json());
app.use('/api/auth', authRoutes);

app.listen(3000, () => {
  console.log("Sunucu 3000 portunda çalışıyor");
});

🧩 routes/authRoutes.js

javascriptCopyEditconst express = require('express');
const router = express.Router();
const { login, register, refreshToken, protectedRoute } = require('../controllers/authController');
const verifyToken = require('../middlewares/authMiddleware');

router.post('/register', register);
router.post('/login', login);
router.post('/token', refreshToken);
router.get('/dashboard', verifyToken, protectedRoute);

module.exports = router;

🧠 controllers/authController.js

javascriptCopyEditconst jwt = require('jsonwebtoken');

const users = []; // Sahte kullanıcı veritabanı

const register = (req, res) => {
  const { username, password } = req.body;
  users.push({ username, password });
  res.json({ message: "Kayıt başarılı" });
};

const login = (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);

  if (!user) return res.status(401).json({ message: 'Kullanıcı bulunamadı' });

  const accessToken = jwt.sign({ username }, process.env.ACCESS_SECRET, { expiresIn: '15m' });
  const refreshToken = jwt.sign({ username }, process.env.REFRESH_SECRET, { expiresIn: '7d' });

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

const refreshToken = (req, res) => {
  const { token } = req.body;
  if (!token) return res.sendStatus(401);

  jwt.verify(token, process.env.REFRESH_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    const newAccessToken = jwt.sign({ username: user.username }, process.env.ACCESS_SECRET, { expiresIn: '15m' });
    res.json({ accessToken: newAccessToken });
  });
};

const protectedRoute = (req, res) => {
  res.json({ message: "Gizli bilgi: JWT ile erişildi!" });
};

module.exports = { register, login, refreshToken, protectedRoute };

🛡️ middlewares/authMiddleware.js

javascriptCopyEditconst jwt = require('jsonwebtoken');

const verifyToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(" ")[1];
  if (!token) return res.sendStatus(401);

  jwt.verify(token, process.env.ACCESS_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
};

module.exports = verifyToken;

🖥️ Postman Test Senaryoları

İşlemHTTPEndpointAçıklama
KayıtPOST/api/auth/registerYeni kullanıcı oluşturur
GirişPOST/api/auth/loginAccess ve refresh token döner
Token yenilePOST/api/auth/tokenRefresh token ile yeni access alınır
KorumaGET/api/auth/dashboardSadece geçerli token ile erişilir

🧑‍💻 React ile JWT Kimlik Doğrulama – Frontend Entegrasyonu

🧱 1. React Projesi Kurulumu

bashCopyEditnpx create-react-app jwt-auth-client
cd jwt-auth-client
npm install axios react-router-dom

📁 Proje Dosya Yapısı

pgsqlCopyEditsrc/
│
├── components/
│   ├── Login.js
│   ├── Register.js
│   ├── Dashboard.js
│
├── services/
│   └── authService.js
│
├── App.js
└── index.js

🔐 authService.js – Token İşlemleri

javascriptCopyEditimport axios from "axios";

const API_URL = "http://localhost:3000/api/auth/";

export const register = async (user) => {
  return await axios.post(API_URL + "register", user);
};

export const login = async (user) => {
  const res = await axios.post(API_URL + "login", user);
  if (res.data.accessToken) {
    localStorage.setItem("accessToken", res.data.accessToken);
    localStorage.setItem("refreshToken", res.data.refreshToken);
  }
  return res.data;
};

export const getProtected = async () => {
  const token = localStorage.getItem("accessToken");
  return await axios.get(API_URL + "dashboard", {
    headers: { Authorization: `Bearer ${token}` },
  });
};

📝 Register.js – Kayıt Sayfası

javascriptCopyEditimport { useState } from "react";
import { register } from "../services/authService";

function Register() {
  const [form, setForm] = useState({ username: "", password: "" });

  const handleSubmit = async (e) => {
    e.preventDefault();
    await register(form);
    alert("Kayıt başarılı!");
  };

  return (
    <form onSubmit={handleSubmit}>
      <h2>Kayıt Ol</h2>
      <input type="text" placeholder="Kullanıcı Adı"
             onChange={(e) => setForm({ ...form, username: e.target.value })} />
      <input type="password" placeholder="Şifre"
             onChange={(e) => setForm({ ...form, password: e.target.value })} />
      <button type="submit">Kayıt</button>
    </form>
  );
}

export default Register;

🔐 Login.js – Giriş Sayfası

javascriptCopyEditimport { useState } from "react";
import { login } from "../services/authService";

function Login() {
  const [form, setForm] = useState({ username: "", password: "" });

  const handleSubmit = async (e) => {
    e.preventDefault();
    const data = await login(form);
    alert(`Hoş geldin ${data.username}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <h2>Giriş Yap</h2>
      <input type="text" placeholder="Kullanıcı Adı"
             onChange={(e) => setForm({ ...form, username: e.target.value })} />
      <input type="password" placeholder="Şifre"
             onChange={(e) => setForm({ ...form, password: e.target.value })} />
      <button type="submit">Giriş</button>
    </form>
  );
}

export default Login;

🔒 Dashboard.js – Korunan Sayfa

javascriptCopyEditimport { useEffect, useState } from "react";
import { getProtected } from "../services/authService";

function Dashboard() {
  const [secret, setSecret] = useState("");

  useEffect(() => {
    getProtected().then(res => setSecret(res.data.message));
  }, []);

  return (
    <div>
      <h2>Gizli Bilgi</h2>
      <p>{secret}</p>
    </div>
  );
}

export default Dashboard;

🚦 App.js – Yönlendirme

javascriptCopyEditimport { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Register from "./components/Register";
import Login from "./components/Login";
import Dashboard from "./components/Dashboard";

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Register />} />
        <Route path="/login" element={<Login />} />
        <Route path="/dashboard" element={<Dashboard />} />
      </Routes>
    </Router>
  );
}

export default App;

🔐 Güvenlik Notları

  • Token’ı localStorage yerine httpOnly cookie ile saklamak daha güvenlidir.
  • Refresh token sistemi ile token süresi bitince yeniden login olmadan güncellenmesi sağlanabilir.
  • CORS ayarları backend tarafında yapılmalıdır.
  • HTTPS kullanımı zorunludur (özellikle production’da).

Review JavaScript ile JWT Oluşturma: Güvenli Kimlik Doğrulamanın Temelleri.

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