Skip to content
Public template

About

JWT auth (access + refresh, httpOnly cookie), rol bazlı yetkilendirme ve güvenlik middleware'leriyle hazır Express 5 + MongoDB başlangıç template'i.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

Express Template

JWT tabanlı auth akışı, rol bazlı yetkilendirme ve temel güvenlik middleware'leriyle hazırlanmış, hızlı başlangıç için Express + MongoDB template projesi.

Özellikler

  • JWT Auth - Access + refresh token, httpOnly cookie ile taşınır
  • Rol Bazlı Yetkilendirme - checkRole middleware'i ile user / editor / admin
  • Path Alias - module-alias ile @/model/user.js gibi importlar
  • Güvenlik - helmet, auth uçlarında express-rate-limit, cookie-parser
  • Logging - morgan ile request logları
  • Env Doğrulama - Boot anında zorunlu değişkenler kontrol edilir, eksikse sunucu açılmaz
  • Postman Koleksiyonu - Hazır istek taslaklarıyla uçtan uca test

Proje Yapısı

node-express-template/
├── src/
│   ├── config/
│   │   └── databaseConfig.js   # Mongo bağlantısı
│   ├── controller/
│   │   └── authController.js   # register, login, logout, tokenRefresh
│   ├── middlewares/
│   │   ├── authMiddleware.js   # verifyAccessToken, verifyRefreshToken
│   │   ├── checkRole.js        # rol bazlı yetkilendirme
│   │   └── rateLimiter.js      # authLimiter
│   ├── model/
│   │   ├── user.js
│   │   └── token.js            # refresh token kayıtları
│   ├── routes/
│   │   ├── authRoute.js
│   │   └── testRoute.js        # middleware'leri denemek için örnek uçlar
│   ├── utils/
│   │   ├── token.js            # generateTokens
│   │   └── validateEnv.js
│   └── server.js               # uygulama giriş noktası
├── .env.example
├── .gitignore
├── package.json
├── postman_collection.json
└── README.md

Kurulum

# Bağımlılıkları yükle
npm install

# .env dosyasını oluştur
cp .env.example .env

# Geliştirme sunucusunu başlat (nodemon)
npm run dev

# Production
npm start

Environment Değişkenleri

.env dosyasını doldur:

Değişken Açıklama
PORT Sunucunun dinleyeceği port
MONGO_URI MongoDB (Atlas veya local) bağlantı string'i
ACCESS_TOKEN_SECRET Access token imzalama secret'ı
REFRESH_TOKEN_SECRET Refresh token imzalama secret'ı

Secret üretmek için:

node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"

Bu dört değişkenden biri eksikse src/utils/validateEnv.js sunucuyu boot anında durdurur:

const REQUIRED_ENV_VARS = [
  "PORT",
  "MONGO_URI",
  "ACCESS_TOKEN_SECRET",
  "REFRESH_TOKEN_SECRET",
];

const validateEnv = () => {
  const missing = REQUIRED_ENV_VARS.filter((key) => !process.env[key]);
  if (missing.length > 0) {
    console.error(
      `Eksik ortam değişkenleri: ${missing.join(", ")}. Lütfen .env dosyanızı kontrol edin.`,
    );
    process.exit(1);
  }
};

Uygulama Giriş Noktası (server.js)

require("module-alias/register");
const dotenv = require("dotenv");
dotenv.config();

const express = require("express");
const helmet = require("helmet");
const morgan = require("morgan");
const cookieParser = require("cookie-parser");
const connectMongoDatabase = require("@/config/databaseConfig.js");
const validateEnv = require("@/utils/validateEnv.js");

validateEnv();

const app = express();

app.use(helmet());
app.use(morgan("dev"));
app.use(express.json());
app.use(cookieParser());

const authRoutes = require("@/routes/authRoute.js");
app.use("/auth", authRoutes);

connectMongoDatabase()
  .then(() => {
    app.listen(process.env.PORT, () => {
      console.log(`Server is running on port ${process.env.PORT}`);
    });
  })
  .catch(() => {
    process.exit(1); // DB bağlanamazsa sunucu ayağa kalkmaz
  });

Auth Akışı

Uçlar (/auth)

Method Path Açıklama
POST /auth/register Yeni kullanıcı oluşturur, cookie'lere token yazar
POST /auth/login Giriş yapar, cookie'lere token yazar
POST /auth/logout Refresh token'ı DB'den siler, cookie'leri temizler
POST /auth/token-refresh Refresh token ile yeni access/refresh token üretir

register ve login uçları authLimiter ile sınırlıdır (15 dakikada IP başına 20 istek).

Route Tanımlama (authRoute.js)

const express = require("express");
const router = express.Router();

const {
  register,
  login,
  logout,
  tokenRefresh,
} = require("@/controller/authController.js");
const { authLimiter } = require("@/middlewares/rateLimiter.js");

router.post("/register", authLimiter, register);
router.post("/login", authLimiter, login);
router.post("/logout", logout);
router.post("/token-refresh", tokenRefresh);

module.exports = router;

Token Üretimi (utils/token.js)

const generateTokens = async (user) => {
  const accessToken = jwt.sign(
    { userId: user._id, email: user.email, role: user.role },
    process.env.ACCESS_TOKEN_SECRET,
    { expiresIn: "15m" },
  );

  const refreshToken = jwt.sign(
    { userId: user._id },
    process.env.REFRESH_TOKEN_SECRET,
    { expiresIn: "7d" },
  );

  // Kullanıcının eski token kaydını sil, yenisini oluştur
  await Token.deleteMany({ userId: user._id });
  await Token.create({ userId: user._id, refreshToken, date: new Date() });

  return { accessToken, refreshToken };
};

Not: Login her seferinde kullanıcının önceki tüm refresh token kayıtlarını siler. Yani aynı kullanıcı ikinci bir cihazdan giriş yaptığında ilk cihazdaki oturum düşer. Çoklu cihaz desteği gerekiyorsa bu mantığın (cihaz başına ayrı token) değiştirilmesi gerekir.

Middleware'ler

verifyAccessToken / verifyRefreshToken (middlewares/authMiddleware.js)

Cookie'den ya da Authorization: Bearer <token> header'ından token'ı okuyup doğrular, geçerliyse req.user'a decode edilmiş payload'ı yazar.

const verifyAccessToken = (req, res, next) => {
  const token =
    req.cookies.accessToken || req.headers["authorization"]?.split(" ")[1];
  if (!token) {
    return res.status(401).json({ message: "Access token bulunamadı." });
  }

  try {
    const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    return res.status(403).json({ message: "Geçersiz access token." });
  }
};

checkRole (middlewares/checkRole.js)

req.user.role'ü, izin verilen roller listesiyle karşılaştırır. verifyAccessToken'dan sonra çalıştırılmalı (req.user'ın dolu olması gerekir).

const checkRole = (...roles) => {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ message: "Kullanıcı doğrulanamadı." });
    }
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({ message: "Bu işlem için yetkiniz yok." });
    }
    next();
  };
};

Korumalı Route Örneği

const { verifyAccessToken } = require("@/middlewares/authMiddleware.js");
const checkRole = require("@/middlewares/checkRole.js");

// Sadece giriş yapmış kullanıcı
router.get("/protected", verifyAccessToken, (req, res) => {
  res.json({ user: req.user });
});

// Sadece admin
router.get("/admin-only", verifyAccessToken, checkRole("admin"), (req, res) => {
  res.json({ user: req.user });
});

Bu middleware'leri denemek için src/routes/testRoute.js altında hazır uçlar var (/test/public, /test/protected, /test/refresh-check, /test/editor-only, /test/admin-only).

API'yi Denemek

Repo kökündeki postman_collection.json dosyasını Postman'e import et. baseUrl değişkeni http://localhost:3005 olarak ayarlı.

  1. Auth > Register veya Auth > Login isteğini çalıştır (Postman cookie'leri otomatik saklar)
  2. Test / Middleware klasöründeki uçları dene

Yeni kayıt olan kullanıcılar varsayılan olarak role: "user" alır. editor-only / admin-only uçlarını denemek için ilgili kullanıcının role alanını MongoDB'de elle güncellemen gerekir.

Yeni Bir Resource Ekleme

Auth dışında yeni bir kaynak (örn. post) eklerken izlenecek sıra:

  1. src/model/post.js — Mongoose şeması
  2. src/controller/postController.js — CRUD fonksiyonları
  3. src/routes/postRoute.js — route tanımları, gerekirse verifyAccessToken / checkRole ile koru
  4. src/server.js içine route'u bağla:
    const postRoutes = require("@/routes/postRoute.js");
    app.use("/posts", postRoutes);

Teknolojiler

  • Express 5
  • MongoDB / Mongoose
  • jsonwebtoken, bcryptjs
  • helmet, express-rate-limit, cookie-parser, cors
  • morgan
  • nodemon (geliştirme)

Not: Bu template proje, JWT tabanlı auth ile hızlı API geliştirme için hazırlanmıştır. İhtiyaca göre özelleştirilebilir (örn. çoklu cihaz oturum desteği, email doğrulama, input validation kütüphanesi eklenmesi).

About

JWT auth (access + refresh, httpOnly cookie), rol bazlı yetkilendirme ve güvenlik middleware'leriyle hazır Express 5 + MongoDB başlangıç template'i.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages