Takip et

Express Auth Boilerplate: Modern API’lar İçin Temiz Mimari

Modern API geliştirme süreçlerinde karşılaşılan en büyük zorluklardan biri, hem hızlı geliştirme döngüsü sağlamak hem de uzun vadede bakımı kolay, ölçeklenebilir ve güvenli bir kod tabanı oluşturmaktır. Bu karmaşık dengeyi sağlamak için sıklıkla temiz mimari prensipleri ve önceden yapılandırılmış şablonlar kullanılır. İşte tam da bu noktada, Express.js tabanlı güçlü bir kimlik doğrulama çözümü sunan Express Auth Boilerplate devreye giriyor.

Günümüzün dijital dünyasında, her türlü uygulamanın belkemiğini API’lar oluşturuyor. Mobil uygulamalardan web sitelerine, IoT cihazlarından mikro hizmetlere kadar her yerde veri alışverişi ve iş mantığı API’lar aracılığıyla yürütülüyor. Ancak bu dinamik ortam, geliştiricileri önemli zorluklarla karşı karşıya bırakıyor. Başlangıçta küçük bir proje olarak tasarlanan bir API, kısa sürede karmaşık bir yapıya dönüşebilir. Bu durum, “spagetti kod” olarak adlandırılan, bakımı zor, yeni özellik eklenmesi riskli ve hata ayıklaması zaman alıcı bir kod tabanına yol açabilir. Projeler büyüdükçe, performans sorunları, güvenlik açıkları ve ölçeklenebilirlik kısıtlamaları gibi engeller de kaçınılmaz hale gelir. Özellikle kimlik doğrulama ve yetkilendirme gibi kritik güvenlik mekanizmaları, yanlış uygulandığında tüm sistemin güvenliğini tehlikeye atabilir.

Peki, bu zorlukların üstesinden nasıl gelinebilir? Çözüm, doğru mimari yaklaşımları benimsemekten ve kanıtlanmış şablonları kullanmaktan geçiyor. Temiz Mimari (Clean Architecture) gibi prensipler, kodun farklı katmanlara ayrılmasını sağlayarak her bir katmanın belirli bir sorumluluğu üstlenmesini hedefler. Bu sayede bağımlılıklar azalır, kod daha modüler hale gelir ve test edilebilirlik artar. Ancak sıfırdan temiz mimariye uygun bir yapı kurmak, özellikle proje zaman çizelgeleri kısıtlı olduğunda, önemli bir başlangıç maliyeti ve öğrenme eğrisi gerektirebilir. İşte bu noktada bir “boilerplate” yani hazır şablon, geliştiricilerin hayatını kolaylaştırır. Express Auth Boilerplate, Node.js ve Express.js ile güvenli ve ölçeklenebilir API’lar geliştirmek isteyen ekipler için temiz mimari prensiplerini uygulayan, önceden yapılandırılmış bir başlangıç noktası sunar. Bu şablon sayesinde geliştiriciler, temel kimlik doğrulama ve yetkilendirme altyapısını kurmakla vakit kaybetmek yerine, doğrudan iş mantığına odaklanabilirler. Böylece hem geliştirme süresi kısalır hem de projenin uzun vadeli sürdürülebilirliği ve güvenliği baştan sağlanmış olur. Bu makale boyunca, Express Auth Boilerplate’in ne olduğunu, neden önemli olduğunu ve modern API’larınızda nasıl kullanabileceğinizi adım adım inceleyeceğiz. Gelişiminizi hızlandıracak, API’larınızı daha sağlam hale getirecek ve ekibinizin verimliliğini artıracak bu güçlü aracı keşfetmeye hazır olun.

Temiz Mimari Nedir ve Express.js ile Nasıl Birleşir?

Temiz Mimari (Clean Architecture), yazılım sistemlerinin bakımını kolaylaştırmak, esnekliğini artırmak ve bağımlılıklarını azaltmak amacıyla Uncle Bob (Robert C. Martin) tarafından ortaya konulan bir tasarım prensipleri kümesidir. Bu mimarinin temel amacı, iş kurallarını (iş mantığını) kullanıcı arayüzü, veritabanı veya harici kütüphaneler gibi uygulama detaylarından ayırmaktır. Bir başka deyişle, yazılımın çekirdeği, çevresel faktörlerden bağımsız ve değiştirilebilir olmalıdır. Temiz mimari, bir dizi eşmerkezli daire şeklinde görselleştirilebilir; iç daireler en soyut ve genel olanı temsil ederken, dış daireler en somut ve uygulamaya özel olanı temsil eder. Bu yapının merkezinde “Entities” (Varlıklar) yer alır ki bunlar uygulamanın ana iş kurallarını ve verilerini içerir. Bir sonraki katman “Use Cases” (Kullanım Durumları) veya “Interactors” olarak adlandırılır; bu katman, uygulamanın özel iş kurallarını ve kullanıcı eylemlerini yönetir. Dış katmanlarda ise “Adapters” (Adaptörler) bulunur; bunlar iç katmanlarla dış katmanlar (veritabanı, UI, API ağ geçitleri) arasında köprü görevi görür. En dış katman ise “Frameworks and Drivers” (Çerçeveler ve Sürücüler) olarak adlandırılır; burada Express.js, veritabanı sürücüleri, UI çerçeveleri gibi somut araçlar bulunur.

Bu yapının en kritik kuralı “Bağımlılık Kuralı”dır: Dış katmanlar iç katmanlara bağımlı olabilirken, iç katmanlar dış katmanlara kesinlikle bağımlı olmamalıdır. Yani, Entities, Use Cases’den haberdar değildir ve Use Cases de Adapters’dan veya Frameworks’ten haberdar değildir. Bu bağımsızlık, uygulamanın çekirdeğinin tamamen soyut kalmasını sağlar ve herhangi bir dış bileşenin değiştirilmesi durumunda iç iş mantığının etkilenmemesini garantiler. Örneğin, bir veritabanı sisteminden diğerine geçiş yapmak, sadece ilgili adaptör katmanında değişiklik yapılmasını gerektirirken, iş kurallarını içeren Use Cases ve Entities katmanları tamamen dokunulmadan kalır. Bu durum, özellikle büyük ölçekli ve uzun ömürlü projelerde bakım kolaylığı, test edilebilirlik ve esneklik açısından muazzam avantajlar sağlar.

Uzman İpucu: Temiz Mimari, bağımlılıkları tek yönlü hale getirerek kod tabanınızın modülerliğini ve test edilebilirliğini önemli ölçüde artırır.

Peki, Express.js gibi bir web çerçevesi bu yapıya nasıl entegre edilir? Express.js, Temiz Mimari’nin en dış katmanı olan “Frameworks and Drivers” katmanına aittir. Routing, middleware yönetimi ve HTTP istek/cevap döngüsü gibi görevleri üstlenir. Express Auth Boilerplate, Express.js’i bu dış katmanda kullanarak, gelen HTTP isteklerini işler, uygun adaptörler aracılığıyla iç katmanlardaki Use Cases’leri tetikler ve sonuçları HTTP yanıtı olarak döndürür. Örneğin, bir kullanıcı kayıt isteği geldiğinde, Express.js rotası bu isteği alır, ilgili “Adapter” (örneğin, bir Controller) isteği ayrıştırır, bu Adapter “Use Case” katmanındaki ‘Kullanıcı Kaydet’ işlevini çağırır. ‘Kullanıcı Kaydet’ Use Case’i, iş kurallarını (örneğin, şifre politikaları) uyguladıktan sonra veriyi “Entity” katmanına uygun hale getirir ve son olarak bir “Gateway” (başka bir adaptör türü, örneğin bir Repository) aracılığıyla veritabanına kaydeder. Bu akış, Express.js’in sadece bir orkestrasyon aracı olarak kullanılmasını ve çekirdek iş mantığından tamamen ayrılmasını sağlar. Böylece, uygulamanızın Express.js yerine başka bir web çerçevesiyle değiştirilmesi gerektiğinde bile, ana iş kurallarınızın sağlam kalacağından emin olabilirsiniz. Bu entegrasyon, API’larınızın sadece fonksiyonel değil, aynı zamanda mimari açıdan da sağlam, esnek ve geleceğe hazır olmasını garantiler.

Express Auth Boilerplate’in Yapı Taşları Nelerdir?

Express Auth Boilerplate, Temiz Mimari prensiplerine sıkı sıkıya bağlı kalarak tasarlanmış modüler bir yapıya sahiptir. Bu yapı, projenin büyüklüğü ne olursa olsun yönetilebilirliğini ve esnekliğini korumasını sağlar. Boilerplate’in temel amacı, kimlik doğrulama (authentication) ve yetkilendirme (authorization) süreçlerini sağlam bir altyapı üzerine oturtmaktır. Genellikle aşağıdaki ana dizin yapısı ve bileşenleri etrafında şekillenir:

  • src/core: Bu katman, uygulamanın çekirdek iş kurallarını ve varlıklarını (entities) barındırır. En soyut ve bağımsız katmandır.
    • entities: Kullanıcı, Rol, Oturum gibi temel iş varlıklarının tanımlandığı yerdir. Bunlar sade JavaScript/TypeScript sınıfları veya arayüzleridir, herhangi bir veritabanı veya çerçeve bağımlılığı içermezler. Örneğin, bir User sınıfı sadece kullanıcıya ait özellikleri (id, email, password, roles) tanımlar.
    • exceptions: Uygulamanın özel hata türlerinin (örn. UserNotFoundException, InvalidCredentialsException) tanımlandığı yerdir. Bu sayede hatalar daha anlamlı ve yapısal hale gelir.
  • src/usecases: “Application Business Rules” katmanıdır. Kullanıcıların veya sistemin gerçekleştirebileceği tüm işlevleri (kullanım durumlarını) içerir. Örneğin, RegisterUserUseCase, LoginUserUseCase, GetUserProfileUseCase gibi işlevler burada bulunur. Her bir kullanım durumu, bağımsız bir iş mantığı parçasını temsil eder ve Entities katmanındaki varlıklar üzerinde işlemler yapar. Bu katman, harici detaylardan tamamen soyutlanmıştır ve veritabanı veya web çerçevesi gibi somut detaylardan habersizdir.
  • src/adapters: Bu katman, iç katmanlar (core, usecases) ile dış katmanlar (frameworks, veritabanı) arasında adaptasyon sağlar. Gelen istekleri iç katmanların anlayacağı formata çevirir ve iç katmanlardan gelen sonuçları dış katmanların anlayacağı formata geri çevirir.
    • controllers: Gelen HTTP isteklerini işler, parametreleri doğrular ve ilgili kullanım durumlarını (use cases) çağırır. Sonuçları HTTP yanıtı olarak döndürmekten sorumludur. Örneğin, AuthController, kayıt ve giriş isteklerini yönetir.
    • repositories: Veritabanı ile etkileşimi soyutlayan arayüzlerdir (interface). IUserRepository gibi arayüzler tanımlanır ve bu arayüzlerin somut uygulamaları (örneğin, bir MongoDB deposu veya PostgreSQL deposu) farklı bir katmanda bulunur. Bu sayede veritabanı sistemi değiştirilse bile Use Cases katmanının etkilenmemesi sağlanır.
    • presenters: Kullanım durumlarından gelen veriyi, kullanıcı arayüzü veya API yanıtı için uygun formata dönüştürür.
    • middleware: Express.js’in standart middleware yapısını kullanarak kimlik doğrulama ve yetkilendirme kontrollerini yapar. JWT token doğrulama veya rol tabanlı erişim kontrolü gibi işlevler burada yer alır.
  • src/frameworks: En dış katmandır ve tüm teknolojiye özel detayları içerir.
    • web: Express.js sunucusunun yapılandırılması, rotaların tanımlanması ve genel hata yönetimi gibi HTTP ile ilgili tüm konular burada yer alır.
    • database: Veritabanı bağlantısı, ORM/ODM (Object-Relational Mapping / Object-Document Mapping) yapılandırması ve Repository arayüzlerinin somut uygulamaları (örn. MongoUserRepository) burada bulunur.
    • config: Ortam değişkenleri, uygulama ayarları ve diğer yapılandırma dosyaları.
    • utils: Yardımcı fonksiyonlar (şifre hashleme, JWT işlemleri vb.) ve üçüncü taraf kütüphane entegrasyonları.

Bu katmanlı yapı sayesinde, örneğin, bir kullanıcı kaydı işlemi aşağıdaki adımları izler:

  1. HTTP isteği src/frameworks/web katmanındaki Express.js router tarafından alınır.
  2. İstek, src/adapters/controllers katmanındaki AuthController‘a iletilir.
  3. AuthController, isteği ayrıştırır ve src/usecases katmanındaki RegisterUserUseCase‘i çağırır.
  4. RegisterUserUseCase, gerekli iş kurallarını uygular (örneğin, e-posta formatını kontrol eder) ve src/core/entities katmanındaki User varlığını kullanır.
  5. RegisterUserUseCase, kullanıcı verilerini kaydetmek için src/adapters/repositories katmanındaki IUserRepository arayüzünü kullanır.
  6. Bu arayüzün somut uygulaması olan src/frameworks/database katmanındaki MongoUserRepository (veya benzeri) veriyi MongoDB’ye kaydeder.
  7. Sonuç, ters bir akışla AuthController‘a geri döner ve HTTP yanıtı olarak kullanıcıya gönderilir.

Bu sayede her bileşen kendi sorumluluğunu bilir, bağımsızdır ve test edilebilirliği yüksektir. Bu modüler yapı, projenin sadece bugünkü değil, yarınki ihtiyaçlarına da kolayca uyum sağlamasına olanak tanır.

Adım Adım Kurulum ve İlk Kullanım: Express Auth Boilerplate Nasıl Başlatılır?

Express Auth Boilerplate’i projenize entegre etmek veya yeni bir projeye başlamak oldukça basittir. Bu adım adım rehber, boilerplate’i sisteminizde nasıl çalıştıracağınızı ve temel bir kullanıcı kayıt/giriş akışını nasıl test edeceğinizi gösterecektir. Temiz mimarinin sağladığı faydaları anında hissedeceksiniz.

1. Önkoşullarınızı Kontrol Edin

Başlamadan önce, sisteminizde aşağıdaki yazılımların kurulu olduğundan emin olun:

  • Node.js: Tercihen LTS (Uzun Süreli Destek) sürümü.
  • npm (Node Package Manager) veya Yarn: Node.js ile birlikte gelir.
  • Git: Depoyu klonlamak için gereklidir.
  • Veritabanı: Boilerplate genellikle MongoDB’yi destekler. Yerel bir MongoDB sunucusu veya bir bulut servisi (örneğin MongoDB Atlas) kullanabilirsiniz.

2. Boilerplate Deponuzu Klonlayın

İlk adım, boilerplate’in kaynak kodunu kendi yerel makinenize indirmektir. Komut satırınızı açın ve aşağıdaki komutu çalıştırın:


  git clone [boilerplate-depo-adresi]
  cd [klonladığınız-klasör-adı]

[boilerplate-depo-adresi] yerine boilerplate'in GitHub veya benzeri bir depodaki URL'sini yapıştırmanız gerekmektedir. Örneğin, eğer bu bir açık kaynak proje ise, URL'yi projenin sayfasında bulabilirsiniz.

3. Bağımlılıkları Yükleyin

Depoyu klonladıktan sonra, projenin ihtiyaç duyduğu tüm Node.js bağımlılıklarını yüklemeniz gerekir. Proje dizinine gittikten sonra aşağıdaki komutlardan birini çalıştırın:


  npm install
  # veya
  yarn install

Bu komut, package.json dosyasında listelenen tüm paketleri indirip node_modules klasörüne yerleştirecektir. Bu süreç, projenin tüm kütüphanelerini ve araçlarını kullanılabilir hale getirir.

4. Ortam Değişkenlerini Yapılandırın (.env)

Boilerplate, hassas bilgileri (veritabanı bağlantı dizeleri, JWT anahtarları vb.) doğrudan kod içinde tutmak yerine ortam değişkenleri aracılığıyla yönetir. Bu, güvenli ve esnek bir yaklaşımdır. Klonladığınız dizinin kökünde genellikle .env.example adında bir dosya bulunur. Bu dosyayı kopyalayarak .env adında yeni bir dosya oluşturun ve kendi ortamınıza uygun şekilde düzenleyin:


  cp .env.example .env

Ardından .env dosyasını açın ve aşağıdaki gibi gerekli bilgileri doldurun:


  NODE_ENV=development
  PORT=3000
  DATABASE_URL=mongodb://localhost:27017/your_database_name
  JWT_SECRET=SUPER_SECRET_KEY_FOR_JWT
  JWT_EXPIRES_IN=1h
  REFRESH_TOKEN_SECRET=ANOTHER_SUPER_SECRET_KEY
  REFRESH_TOKEN_EXPIRES_IN=7d

DATABASE_URL'yi kendi MongoDB bağlantı dizenizle değiştirmeniz çok önemlidir. JWT_SECRET ve REFRESH_TOKEN_SECRET için güçlü, rastgele anahtarlar kullanmalısınız. Bunları üretim ortamında asla varsayılan değerlerle bırakmayın.

Uzman İpucu: Üretim ortamında hassas verilerinizi .env dosyası yerine, bulut sağlayıcınızın ortam değişkeni yönetim sistemlerini (AWS Secrets Manager, Azure Key Vault vb.) kullanarak saklayın. Bu, güvenlik seviyesini önemli ölçüde artıracaktır.

5. Sunucuyu Başlatın

Her şey hazır olduğunda, sunucuyu başlatmak için aşağıdaki komutu kullanabilirsiniz:


  npm run dev
  # veya
  yarn dev

Bu komut, projenizi geliştirme modunda çalıştıracak ve genellikle dosya değişikliklerini otomatik olarak algılayıp sunucuyu yeniden başlatacaktır (nodemon gibi bir araç kullanılıyorsa). Konsolda "Server running on port 3000" gibi bir mesaj görmelisiniz.

6. İlk Kullanıcı Kaydını ve Girişini Test Edin

Sunucu başarıyla çalıştığında, API'nızın uç noktalarına istek göndererek temel işlevleri test edebilirsiniz. Bunun için Postman, Insomnia veya cURL gibi araçları kullanabilirsiniz. Aşağıda örnek bir kullanıcı kayıt ve giriş akışı için cURL komutları bulunmaktadır:

Kullanıcı Kaydı (Register):

/api/v1/auth/register uç noktasına bir POST isteği gönderin.


  curl -X POST -H "Content-Type: application/json" -d '{
    "email": "test@example.com",
    "password": "Password123!"
  }' http://localhost:3000/api/v1/auth/register

Başarılı bir kayıt sonrası, kullanıcı objesi veya bir başarı mesajı almalısınız. Hata durumunda ise ilgili hata mesajını göreceksiniz.

Kullanıcı Girişi (Login):

/api/v1/auth/login uç noktasına bir POST isteği gönderin.


  curl -X POST -H "Content-Type: application/json" -d '{
    "email": "test@example.com",
    "password": "Password123!"
  }' http://localhost:3000/api/v1/auth/login

Başarılı bir giriş sonrası, genellikle bir JWT erişim token'ı (access token) ve bir yenileme token'ı (refresh token) almalısınız. Erişim token'ı, yetkilendirme gerektiren diğer API uç noktalarına istek gönderirken kullanılacaktır.


  {
    "message": "Login successful",
    "data": {
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    }
  }

Bu adımları tamamladığınızda, Express Auth Boilerplate'i başarıyla kurmuş ve temel kimlik doğrulama işlevlerini test etmiş olacaksınız. Artık kendi iş mantığınızı ve özelliklerinizi bu sağlam temel üzerine inşa etmeye başlayabilirsiniz. Geliştirme sürecine başlarken Temiz Mimari prensiplerine sadık kalmak, projenizin uzun ömürlü ve yönetilebilir olmasını sağlayacaktır.

Kullanıcı Kimlik Doğrulama ve Yetkilendirme Akışları Nasıl Yönetilir?

Modern API'ların en kritik bileşenlerinden ikisi, kullanıcıların kimliğini doğrulamak (Authentication) ve onların belirli kaynaklara erişim yetkilerini belirlemek (Authorization) işlemleridir. Express Auth Boilerplate, bu süreçleri Temiz Mimari prensipleriyle entegre ederek hem güvenli hem de esnek bir yapı sunar. JWT (JSON Web Token) kullanımı, bu boilerplate'in temelini oluşturur ve API'lar için durumsuz (stateless) bir kimlik doğrulama mekanizması sağlar.

1. Kullanıcı Kayıt (Register) ve Giriş (Login) İşlemleri

Kullanıcı kayıt ve giriş işlemleri, src/usecases katmanında tanımlanan özel kullanım durumları (use cases) aracılığıyla yönetilir. Örneğin, bir RegisterUserUseCase ve LoginUserUseCase bulunur.

  • Kayıt (Register): Kullanıcı e-posta ve şifre gibi temel bilgileri gönderdiğinde, AuthController bu isteği alır ve RegisterUserUseCase'i çağırır. RegisterUserUseCase, iş kurallarını (örn. şifre güvenliği, e-posta formatı kontrolü) uygular, şifreyi güvenli bir şekilde hashler (genellikle bcrypt kullanarak) ve kullanıcıyı veritabanına kaydeder.
    
              // src/usecases/auth/RegisterUserUseCase.ts
              import { IUserRepository } from '../../adapters/repositories/IUserRepository';
              import { User } from '../../core/entities/User';
              import { HashService } from '../../frameworks/utils/HashService';
    
              export class RegisterUserUseCase {
                constructor(
                  private userRepository: IUserRepository,
                  private hashService: HashService
                ) {}
    
                async execute(email: string, password: string): Promise {
                  // İş kuralları: Email formatı, şifre gücü vb.
                  // ...
    
                  const hashedPassword = await this.hashService.hash(password);
                  const newUser = User.create(email, hashedPassword); // Entity oluşturma
                  return this.userRepository.save(newUser);
                }
              }
            

  • Giriş (Login): Kullanıcı giriş yaptığında, LoginUserUseCase çağrılır. Bu kullanım durumu, kullanıcının girdiği şifreyi veritabanındaki hashlenmiş şifre ile karşılaştırır. Eşleşme durumunda, kullanıcı için bir erişim token'ı (access token) ve bir yenileme token'ı (refresh token) oluşturulur. Bu token'lar, JWT mekanizması kullanılarak imzalanır ve kullanıcıya geri döndürülür.
    
              // src/usecases/auth/LoginUserUseCase.ts
              import { IUserRepository } from '../../adapters/repositories/IUserRepository';
              import { HashService } from '../../frameworks/utils/HashService';
              import { JWTService } from '../../frameworks/utils/JWTService';
              import { InvalidCredentialsException } from '../../core/exceptions/InvalidCredentialsException';
    
              export class LoginUserUseCase {
                constructor(
                  private userRepository: IUserRepository,
                  private hashService: HashService,
                  private jwtService: JWTService
                ) {}
    
                async execute(email: string, password: string): Promise {
                  const user = await this.userRepository.findByEmail(email);
                  if (!user || !(await this.hashService.compare(password, user.password))) {
                    throw new InvalidCredentialsException('Geçersiz e-posta veya şifre.');
                  }
    
                  const accessToken = this.jwtService.generateAccessToken(user.id, user.roles);
                  const refreshToken = this.jwtService.generateRefreshToken(user.id);
    
                  // Refresh token'ı veritabanında saklama veya başka bir mekanizma ile ilişkilendirme
                  // ...
    
                  return { accessToken, refreshToken };
                }
              }
            

2. JWT Token Oluşturma ve Doğrulama

JWT, JSON tabanlı, güvenli bir şekilde bilgi alışverişi yapmak için kullanılan kompakt ve URL güvenli bir yöntemdir. Express Auth Boilerplate'de, src/frameworks/utils/JWTService.ts gibi bir yardımcı sınıf, token oluşturma ve doğrulama işlemlerini kapsüller. Erişim token'ı kısa ömürlüdür ve her istekte Authorization başlığında Bearer şemasıyla gönderilir. Yenileme token'ı ise daha uzun ömürlüdür ve erişim token'ının süresi dolduğunda yenisini almak için kullanılır.


  // src/frameworks/utils/JWTService.ts
  import jwt from 'jsonwebtoken';
  import config from '../../config';

  export class JWTService {
    generateAccessToken(userId: string, roles: string[]): string {
      return jwt.sign({ userId, roles }, config.jwt.secret, {
        expiresIn: config.jwt.expiresIn,
      });
    }

    generateRefreshToken(userId: string): string {
      return jwt.sign({ userId }, config.refreshToken.secret, {
        expiresIn: config.refreshToken.expiresIn,
      });
    }

    verifyAccessToken(token: string): any {
      return jwt.verify(token, config.jwt.secret);
    }

    verifyRefreshToken(token: string): any {
      return jwt.verify(token, config.refreshToken.secret);
    }
  }

3. Middleware Kullanımı ile Kimlik Doğrulama

Geleneksel Express.js uygulamalarında olduğu gibi, boilerplate'de de kimlik doğrulama ve yetkilendirme için middleware'ler kullanılır. src/adapters/middleware/AuthMiddleware.ts gibi bir dosya, gelen isteğin Authorization başlığındaki JWT token'ını doğrulamaktan sorumludur. Token geçerliyse, kullanıcı bilgileri (ID, roller vb.) req objesine eklenir ve istek bir sonraki işleyiciye (handler) iletilir. Eğer token yoksa veya geçersizse, genellikle 401 (Unauthorized) yanıtı döndürülür.


  // src/adapters/middleware/AuthMiddleware.ts
  import { Request, Response, NextFunction } from 'express';
  import { JWTService } from '../../frameworks/utils/JWTService';

  export const authMiddleware = (jwtService: JWTService) => (
    req: Request,
    res: Response,
    next: NextFunction
  ) => {
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return res.status(401).json({ message: 'Erişim token\'ı bulunamadı.' });
    }

    const token = authHeader.split(' ')[1];
    try {
      const decoded = jwtService.verifyAccessToken(token);
      // req.user = decoded; // Kullanıcı bilgilerini isteğe ekle
      next();
    } catch (error) {
      return res.status(401).json({ message: 'Geçersiz veya süresi dolmuş token.' });
    }
  };

4. Yetkilendirme Mekanizmaları (Rol Tabanlı Erişim Kontrolü - RBAC)

Kimlik doğrulama, kullanıcının kim olduğunu belirlerken, yetkilendirme kullanıcının neye erişebileceğini belirler. Boilerplate, genellikle rol tabanlı erişim kontrolü (RBAC) için bir mekanizma sunar. Kullanıcılar, kayıt sırasında veya bir yönetici tarafından belirli rollerle (örn. 'admin', 'editor', 'user') etiketlenir. JWT token'ına bu roller dahil edilebilir. Ardından, bir kaynağa erişim gerektiren rotalara özel yetkilendirme middleware'ları eklenebilir. Bu middleware, kullanıcının JWT'sindeki rolleri kontrol ederek, istenen kaynağa erişim yetkisinin olup olmadığını belirler.


  // src/adapters/middleware/RoleMiddleware.ts
  import { Request, Response, NextFunction } from 'express';
  import { UnauthorizedException } from '../../core/exceptions/UnauthorizedException';

  export const authorizeRoles = (requiredRoles: string[]) => (
    req: Request,
    res: Response,
    next: NextFunction
  ) => {
    // req.user objesinden rolleri alın (AuthMiddleware tarafından eklenmiş olmalı)
    const userRoles = (req as any).user?.roles || [];

    const hasPermission = requiredRoles.some(role => userRoles.includes(role));
    if (!hasPermission) {
      return res.status(403).json({ message: 'Bu kaynağa erişim yetkiniz yok.' });
    }
    next();
  };

Bu middleware'lar, Express.js rotalarına kolayca eklenebilir:


  // src/frameworks/web/routes/userRoutes.ts
  import { Router } from 'express';
  import { authMiddleware } from '../../adapters/middleware/AuthMiddleware';
  import { authorizeRoles } from '../../adapters/middleware/RoleMiddleware';
  // ... diğer importlar

  const router = Router();
  // ... authService, jwtService, vs. injection

  router.get(
    '/profile',
    authMiddleware(jwtService),
    (req, res) => { /* Kullanıcı profili getir */ }
  );

  router.post(
    '/admin/users',
    authMiddleware(jwtService),
    authorizeRoles(['admin']), // Sadece admin rolüne sahip kullanıcılar erişebilir
    (req, res) => { /* Yeni kullanıcı oluştur */ }
  );

Bu şekilde, Express Auth Boilerplate, sağlam bir kimlik doğrulama ve yetkilendirme altyapısı sağlayarak API'larınızın güvenliğini ve erişim kontrolünü etkili bir şekilde yönetmenize olanak tanır. Her bir bileşenin kendi sorumluluğunu üstlenmesi ve Temiz Mimari prensiplerine uygun olarak ayrılması, bu karmaşık süreçleri daha anlaşılır ve yönetilebilir kılar.

Performans ve Güvenlik İyileştirmeleri: Modern API'lar İçin İpuçları Nelerdir?

Bir API'nin başarısı, yalnızca işlevselliğiyle değil, aynı zamanda performansı ve güvenliğiyle de ölçülür. Express Auth Boilerplate, Temiz Mimari'nin sağladığı temel güvenliği ve modülerliği zaten sunarken, modern API'lar için ek performans ve güvenlik iyileştirmeleri yapmak projenizin kalitesini ve dayanıklılığını artıracaktır. Bu bölümde, deneyimli geliştiriciler için ileri düzey ipuçlarını ve püf noktalarını ele alacağız.

1. Güçlü Hashing Algoritmaları ve Tuzlama

Şifrelerin düz metin olarak saklanması asla kabul edilemez. Şifreleri hashlemek, bir gereklilikten öte bir zorunluluktur. Express Auth Boilerplate, genellikle bcrypt gibi kanıtlanmış bir hashing algoritması kullanır. Bcrypt, şifreleri tek yönlü bir hash'e dönüştürmekle kalmaz, aynı zamanda her hash işlemi için benzersiz bir "tuz" (salt) üreterek gökkuşağı tabloları (rainbow tables) gibi saldırılara karşı direnç sağlar. Ayrıca, iş yükünü (cost factor) ayarlayarak hashleme süresini artırabilir, bu da kaba kuvvet saldırılarına karşı daha fazla güvenlik sağlar. Üretim ortamında, bu iş yükü faktörünü sunucunuzun performansını aşırı etkilemeyecek ancak yeterince dirençli olacak şekilde ayarlamak önemlidir.


  // src/frameworks/utils/HashService.ts (Örnek bcrypt kullanımı)
  import bcrypt from 'bcrypt';
  import config from '../../config'; // Tuzlama faktörü buradan alınabilir

  export class HashService {
    private readonly saltRounds: number;

    constructor() {
      this.saltRounds = config.bcrypt.saltRounds || 10; // Varsayılan 10
    }

    async hash(password: string): Promise {
      return bcrypt.hash(password, this.saltRounds);
    }

    async compare(password: string, hash: string): Promise {
      return bcrypt.compare(password, hash);
    }
  }

2. Güvenlik Mekanizmaları: Helmet.js ve Rate Limiting

Express uygulamaları için Helmet.js, çeşitli HTTP başlıklarını ayarlayarak bilinen web güvenlik açıklarının birçoğundan korunmaya yardımcı olan bir middleware koleksiyonudur. Örneğin, XSS (Cross-Site Scripting), CSRF (Cross-Site Request Forgery) ve diğer code injection saldırılarını önlemeye yardımcı olabilir. Projenizin src/frameworks/web/server.ts dosyasında uygulamanızın ilk başlangıcında bu middleware'i eklemek kritik öneme sahiptir.


  // src/frameworks/web/server.ts (Örnek Helmet.js kullanımı)
  import express from 'express';
  import helmet from 'helmet';

  const app = express();
  app.use(helmet()); // Tüm güvenlik başlıklarını otomatik olarak ayarlar
  // ... diğer middleware'ler ve rotalar

Rate limiting (oran sınırlama), API'nizi kötü niyetli veya aşırı kullanımdan korumak için hayati öneme sahiptir. Giriş denemeleri, şifre sıfırlama istekleri veya belirli hassas uç noktalar için bir kullanıcı veya IP adresinden belirli bir süre içinde gelen istek sayısını sınırlayabilirsiniz. Bu, kaba kuvvet saldırılarını veya hizmet reddi (DoS) saldırılarını önlemeye yardımcı olur. express-rate-limit gibi kütüphaneler bu konuda yardımcı olabilir.


  // src/frameworks/web/server.ts (Örnek Rate Limiting kullanımı)
  import rateLimit from 'express-rate-limit';

  const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 dakika
    max: 100, // Her IP için 15 dakikada 100 istek
    message: 'Çok fazla istek, lütfen daha sonra tekrar deneyin.',
  });

  // Belirli rotalara uygulayın
  app.use('/api/v1/auth/login', limiter);
  app.use('/api/v1/auth/register', limiter);

3. Veritabanı Optimizasyonu

Performansın önemli bir kısmı veritabanı işlemlerinden gelir. N+1 sorgu sorunlarını önlemek, doğru indeksleri kullanmak ve karmaşık sorgular için optimize edilmiş yaklaşımlar geliştirmek çok önemlidir. ORM/ODM kullanıyorsanız (örneğin Mongoose), "populate" veya "select" gibi özellikleri akıllıca kullanarak sadece ihtiyacınız olan verileri çekmeye özen gösterin. Temiz Mimari sayesinde, veritabanı etkileşimleri Repository katmanında kapsüllendiği için, optimizasyonlar bu katmanda yoğunlaşabilir ve uygulamanın geri kalanını etkilemez.

4. Cacheleme Stratejileri

Sıkça erişilen ve nadiren değişen veriler için cacheleme kullanmak, veritabanı yükünü azaltarak API yanıt sürelerini önemli ölçüde hızlandırabilir. Redis gibi bir in-memory veri deposu, kullanıcı oturumları, sıkça istenen ürün listeleri veya konfigürasyon verileri için etkili bir önbellek çözümü sunar. Cacheleme mantığını, src/adapters/gateways veya src/frameworks/utils katmanlarında soyutlayarak Temiz Mimari prensiplerine uygun kalabilirsiniz.

5. Sağlıklı Logging ve Hata İzleme

Üretim ortamındaki sorunları hızlıca tespit etmek ve çözmek için kapsamlı logging (kayıt tutma) ve hata izleme sistemleri vazgeçilmezdir. Winston veya Pino gibi kütüphanelerle yapılandırılmış bir loglama sistemi, uygulama davranışını, istek/yanıt döngülerini ve hata durumlarını detaylı bir şekilde kaydetmelidir. Sentry veya New Relic gibi hata izleme araçları, hataları gerçek zamanlı olarak yakalamanıza, hata bağlamını anlamanıza ve üretim sorunlarına proaktif bir şekilde müdahale etmenize olanak tanır. Uygulamanızın her katmanında anlamlı log mesajları üretmek, hata ayıklama sürecini büyük ölçüde hızlandırır.


  // src/frameworks/utils/Logger.ts (Basit bir logger örneği)
  import winston from 'winston';

  const logger = winston.createLogger({
    level: 'info',
    format: winston.format.combine(
      winston.format.timestamp(),
      winston.format.json()
    ),
    transports: [
      new winston.transports.Console(),
      new winston.transports.File({ filename: 'error.log', level: 'error' }),
      new winston.transports.File({ filename: 'combined.log' }),
    ],
  });

  export { logger };

Bu iyileştirmeleri Express Auth Boilerplate ile birleştirmek, sadece fonksiyonel değil, aynı zamanda yüksek performanslı, güvenli ve sürdürülebilir modern API'lar oluşturmanıza yardımcı olacaktır. Her bir optimizasyonun, uygulamanızın genel sağlığına nasıl katkıda bulunduğunu düşünerek ilerlemeniz önemlidir.

Vaka Analizi: Büyük Ölçekli Bir Projede Express Auth Boilerplate Nasıl Kullanılır?

Bir e-ticaret platformu veya SaaS (Hizmet Olarak Yazılım) uygulaması gibi büyük ölçekli projeler, karmaşık iş mantığı, yüksek kullanıcı trafiği ve sürekli genişleyen özellik setleriyle karakterize edilir. Bu tür projelerde, "spagetti kod" tuzağına düşmek ve bakım kabiliyetini kaybetmek oldukça kolaydır. İşte bu noktada Express Auth Boilerplate'in Temiz Mimari yaklaşımı, geliştirme sürecini dönüştürebilecek kritik bir avantaj sunar. Gelin, hayali bir "GlobalE-Ticaret" platformunun bu boilerplate'i nasıl kullandığına dair bir vaka analizini inceleyelim.

Senaryo: GlobalE-Ticaret Platformu

GlobalE-Ticaret, dünya çapında milyonlarca kullanıcısı olan, binlerce satıcıyı ve milyonlarca ürünü barındıran kapsamlı bir e-ticaret platformudur. Platform, ürün listeleme, sepet yönetimi, ödeme işlemleri, kullanıcı profilleri, sipariş takibi ve satıcı paneli gibi birçok mikro hizmetten oluşan karmaşık bir API altyapısına sahiptir. Başlangıçta monolotik bir yapıyla başlanmış ancak hızla ölçeklenebilirlik, bakım kolaylığı ve takım içi işbirliği sorunları yaşanmıştır. Bu sorunları aşmak için API'lar mikro hizmetlere ayrıştırılmış ve her bir mikro hizmet için Temiz Mimari prensiplerine dayalı Express Auth Boilerplate kullanma kararı alınmıştır.

Ölçeklenebilirlik Zorlukları ve Boilerplate'in Katkıları

  1. Kullanıcı Yönetimi ve Kimlik Doğrulama Mikro Hizmeti: GlobalE-Ticaret'in en kritik bileşenlerinden biri, milyonlarca kullanıcının kayıt, giriş, şifre sıfırlama, rol yönetimi gibi işlemlerini yöneten "Auth Service" idi. Başlangıçtaki monolotik yapı, bu işlemleri merkezi bir noktada tuttuğu için performans darboğazlarına ve güvenlik risklerine yol açıyordu. Express Auth Boilerplate kullanılarak, Auth Service tamamen bağımsız bir mikro hizmet olarak yeniden tasarlandı.
    • Avantajı: Boilerplate'in sağlam JWT tabanlı kimlik doğrulama mekanizması sayesinde, kullanıcı girişleri hızlı ve güvenli bir şekilde işlendi. Temiz Mimari, iş kurallarını (şifre hashleme, JWT oluşturma) altyapı detaylarından (Express.js, veritabanı) ayırdığı için, Auth Service ek yük olmadan yüksek trafikte çalışabildi ve kolayca yatay olarak ölçeklenebildi.
    • Vaka: Kara Cuma gibi yoğun dönemlerde Auth Service, milyonlarca eş zamanlı giriş isteğini hiçbir performans düşüşü yaşamadan işleyebildi, çünkü iş mantığı tamamen optimize edilmiş ve izole edilmişti.
  2. Ürün ve Sipariş Yönetimi Mikro Hizmetleri: Auth Service'den ayrı olarak, "Product Service" ve "Order Service" gibi diğer mikro hizmetler de boilerplate'in sağladığı temel yapıyı kullandı. Bu hizmetler, Auth Service'den gelen JWT token'larını kullanarak kullanıcıların kimliğini doğruladı ve yetkilendirme middleware'ları ile erişim kontrolleri uyguladı.
    • Avantajı: Temiz Mimari, her mikro hizmetin kendi iş mantığını bağımsız olarak geliştirmesine olanak tanıdı. Örneğin, Product Service'deki "ürün ekle" işlemi, sadece 'admin' veya 'seller' rolüne sahip kullanıcılar tarafından yapılabiliyordu. Bu yetkilendirme mantığı, kolayca entegre edilen boilerplate middleware'ları ile sağlandı.
    • Vaka: Yeni satıcıların ürünlerini yüklemesi veya siparişlerin işlenmesi gibi işlemler, farklı mikro hizmetler tarafından yönetilse de, tutarlı bir kimlik doğrulama ve yetkilendirme standardı sayesinde sorunsuz bir entegrasyon sağlandı.

Ek Özelliklerin Entegrasyonu

GlobalE-Ticaret platformu, zamanla ödeme sistemleri entegrasyonu, bildirim hizmetleri (e-posta, SMS), indirim kodları yönetimi gibi birçok ek özellik gerektirdi. Express Auth Boilerplate'in modüler yapısı, bu entegrasyonları kolaylaştırdı:

  • Ödeme Sistemleri: Ödeme hizmetleri (Stripe, PayPal) için src/adapters/gateways katmanında özel adaptörler oluşturuldu. Bu sayede, ödeme mantığı çekirdek iş kurallarından ayrıldı ve farklı ödeme sağlayıcıları arasında geçiş yapmak oldukça kolaylaştı.
    
              // src/adapters/gateways/IPaymentGateway.ts
              interface IPaymentGateway {
                charge(amount: number, token: string): Promise;
              }
    
              // src/frameworks/integrations/StripePaymentGateway.ts
              class StripePaymentGateway implements IPaymentGateway { /* ... */ }
            

  • Bildirimler: Kullanıcı kayıtları, sipariş güncellemeleri gibi olaylar için bildirim göndermek amacıyla src/usecases katmanında SendEmailNotificationUseCase gibi kullanım durumları tanımlandı ve bu kullanım durumları src/adapters/gateways katmanında IEmailService arayüzü ile soyutlandı. Somut uygulamalar (örneğin SendGrid veya Mailgun entegrasyonları) src/frameworks/integrations altında yer aldı.

Takım İçindeki İşbirliğine Etkisi

Boilerplate'in sağladığı en büyük faydalardan biri, farklı geliştirme ekiplerinin aynı standartları ve mimari prensipleri benimsemesini sağlamasıydı. Her yeni mikro hizmet projesi aynı dizin yapısı, katmanlama ve kodlama standartlarıyla başlıyordu. Bu durum:

  • Öğrenme Eğrisini Azalttı: Yeni ekip üyeleri veya farklı mikro hizmetlere geçen geliştiriciler, hızlıca adapte olabildi çünkü tüm projeler benzer bir yapıya sahipti.
  • Kod Kalitesini Artırdı: Temiz Mimari prensiplerine uyum, daha okunabilir, test edilebilir ve sürdürülebilir kod üretilmesini teşvik etti.
  • Sürekli Entegrasyon/Sürekli Dağıtım (CI/CD) Kolaylığı: Standartlaştırılmış yapı, otomatik testlerin ve dağıtım pipeline'larının kurulmasını basitleştirdi.
Uzman İpucu: Büyük ekiplerde, boilerplate kullanımı standartlaşmayı sağlayarak "ortak dil" oluşturur ve geliştirici verimliliğini %30'a kadar artırabilir.

Sonuç olarak, GlobalE-Ticaret gibi karmaşık bir projede Express Auth Boilerplate kullanımı, sadece kimlik doğrulama ve yetkilendirme sorunlarını çözmekle kalmadı, aynı zamanda projenin genel mimari kalitesini yükselterek ölçeklenebilirliği, bakım kolaylığını ve takım içi işbirliğini önemli ölçüde geliştirdi. Bu vaka analizi, Temiz Mimari'nin ve iyi tasarlanmış bir boilerplate'in gerçek dünyadaki değerini açıkça ortaya koymaktadır.

Sonuç ve Sıkça Sorulan Sorular

Modern API geliştirmenin karmaşık dünyasında, performans, güvenlik ve sürdürülebilirlik gibi faktörleri bir arada sağlamak hiç bu kadar önemli olmamıştı. Bu makale boyunca, Express Auth Boilerplate'in Temiz Mimari prensiplerini Express.js ile nasıl birleştirerek geliştiricilere güçlü, modüler ve ölçeklenebilir bir başlangıç noktası sunduğunu detaylıca inceledik. Gerek temel kurulum adımları, gerekse ileri düzey performans ve güvenlik iyileştirmeleri ve gerçek dünya vaka analiziyle, bu boilerplate'in modern API ihtiyaçlarını karşılamak için ne kadar uygun olduğunu görmüş olduk.

Express Auth Boilerplate, sadece hızlı bir başlangıç sağlamakla kalmaz, aynı zamanda projenizin uzun vadeli sağlığını da garanti altına alır. Katmanlı yapısı sayesinde, iş mantığınızı altyapı detaylarından ayırarak test edilebilirliği artırır, bağımlılıkları azaltır ve gelecekteki değişikliklere karşı esneklik sunar. Kimlik doğrulama ve yetkilendirme gibi kritik güvenlik bileşenlerini güvenli ve standart bir şekilde yönetmesi, geliştiricilerin güvenlik endişeleriyle boğuşmak yerine doğrudan iş değerine odaklanmasını sağlar. Sonuç olarak, bu boilerplate, karmaşık Node.js API'ları geliştiren her ekip için değerli bir varlıktır. Umuyoruz ki bu makale, Express Auth Boilerplate'i projelerinize entegre etmeniz ve modern API geliştirme yolculuğunuzda size rehberlik etmeniz için ilham vermiştir.

Sıkça Sorulan Sorular (SSS)

1. Express Auth Boilerplate sadece kimlik doğrulama için mi kullanılır?

Hayır, Express Auth Boilerplate temel olarak güçlü bir kimlik doğrulama ve yetkilendirme altyapısı sunsa da, Temiz Mimari prensipleri üzerine inşa edildiği için her türlü iş mantığını entegre etmek için genişletilebilir. Kayıt, giriş ve rol tabanlı erişim kontrolü gibi temel auth özelliklerini sağlarken, aynı zamanda iş kurallarınızı ve yeni özelliklerinizi modüler bir şekilde eklemeniz için sağlam bir temel sunar.

2. Bu boilerplate hangi veritabanı sistemlerini destekler?

Boilerplate, Temiz Mimari'nin esnekliği sayesinde veritabanı bağımsızdır. Genellikle MongoDB gibi NoSQL veritabanlarıyla örnekler sunulsa da, src/adapters/repositories katmanındaki arayüzler ve src/frameworks/database katmanındaki somut uygulamalar değiştirilerek PostgreSQL, MySQL veya diğer veritabanlarıyla da kolayca entegre edilebilirsiniz. Tek yapmanız gereken, seçtiğiniz veritabanına uygun bir Repository uygulamasını yazmak ve mevcut arayüzleri uygulamaktır.

3. Express Auth Boilerplate'i mevcut bir Express projesine entegre edebilir miyim?

Evet, teorik olarak entegre edebilirsiniz, ancak bu biraz çaba gerektirebilir. Mevcut projenizin mimarisi ve dosya yapısı ne kadar Temiz Mimari prensiplerine yakınsa, entegrasyon o kadar kolay olacaktır. Genellikle, boilerplate'in src/core, src/usecases ve src/adapters katmanlarını mevcut projenizin ilgili bölümlerine taşımak ve src/frameworks katmanındaki Express.js yapılandırmasını kendi projenize uyarlamak gerekebilir. Büyük çaplı entegrasyonlar yerine yeni bir projeyi bu boilerplate ile başlatmak genellikle daha verimli olabilir.

4. JWT yerine başka bir kimlik doğrulama yöntemi kullanabilir miyim?

Evet, kullanabilirsiniz. Temiz Mimari'nin bir diğer güzelliği de budur. JWT ile ilgili tüm mantık (token oluşturma, doğrulama) src/frameworks/utils/JWTService.ts gibi bir yardımcı serviste kapsüllendiği için, bu servisi başka bir kimlik doğrulama yöntemi (örneğin oturum tabanlı kimlik doğrulama veya OAuth sağlayıcıları) ile değiştirebilirsiniz. Sadece JWTService'in arayüzüne uygun yeni bir servis oluşturmanız ve bunu ilgili Use Case'lere enjekte etmeniz yeterlidir. Çekirdek iş mantığınız etkilenmeyecektir.

5. Bu boilerplate mobil uygulamalar için uygun mu?

Kesinlikle! Express Auth Boilerplate ile oluşturulan API'lar RESTful (veya GraphQL) prensiplerine uygun çalıştığı için, mobil uygulamalar (iOS, Android, React Native), tek sayfa uygulamaları (SPA'lar) veya diğer herhangi bir istemci uygulaması tarafından kolayca tüketilebilir. JWT token'ları, mobil cihazlarda güvenli bir şekilde saklanabilir ve API isteklerinde kimlik doğrulama için kullanılabilir. Boilerplate'in sunduğu güvenli ve ölçeklenebilir API yapısı, mobil uygulamaların ihtiyaç duyduğu performansı ve veri güvenliğini fazlasıyla karşılar.

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

Gönder

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.
Mobil sürümden çık