NestJS Güvenliği: 7 Adımda Kapsamlı Rehber [2026]
Yazar: Burak Balkı | Kategori: Security | Okuma Süresi: 56 dk
2026 yılında NestJS uygulamalarınızı siber tehditlere karşı korumak için gerekli temel ve ileri seviye güvenlik tekniklerini adım adım öğrenin. Bu kapsamlı r...
## NestJS Güvenliği: 7 Adımda Kapsamlı Rehber [2026]
Her yıl siber saldırıların maliyeti katlanarak artarken, 2026 verilerine göre küçük ve orta ölçekli işletmelerin bile %60'ından fazlası siber güvenlik ihlalleriyle karşılaşıyor. Bu kritik tablo karşısında, modern web uygulamalarının temelini oluşturan framework'lerin güvenliği her zamankinden daha hayati hale gelmiştir. Bu kapsamlı rehberde, NestJS'in güçlü yapısını kullanarak uygulamalarınızı 2026'nın en güncel tehditlerine karşı nasıl güçlendireceğinizi adım adım öğrenecek, pratik kod örnekleriyle kendi güvenli NestJS projenizi sıfırdan inşa edeceksiniz. Bu sayede hem veri ihlallerini önleyecek hem de kullanıcılarınızın güvenini kazanacaksınız.
## NestJS Güvenliği Nedir?
NestJS güvenliği, NestJS framework'ü ile geliştirilen web uygulamalarını, potansiyel siber saldırılara, veri ihlallerine ve kötü niyetli aktivitelere karşı korumak için uygulanan yöntemler, araçlar ve en iyi uygulamalar bütünüdür. Bu, uygulamanın tüm katmanlarında (veritabanı, API, kullanıcı arayüzü, sunucu) güvenlik açıklarını tespit etmeyi, önlemeyi ve azaltmayı hedefler. Temel olarak, kimlik doğrulama, yetkilendirme, veri bütünlüğü, gizlilik ve sistemin kullanılabilirliğini sağlamayı amaçlar.
Detaylı açıklamak gerekirse, NestJS, Node.js ekosisteminin en popüler ve kurumsal düzeyde kabul görmüş framework'lerinden biridir. TypeScript desteği, modüler yapısı ve Angular esintili mimarisiyle büyük ölçekli uygulamaların geliştirilmesini kolaylaştırır. Ancak bu güç, beraberinde güvenlik sorumluluğunu da getirir. NestJS güvenliği, OWASP Top 10 gibi bilinen güvenlik risklerini (Injection, Broken Authentication, Sensitive Data Exposure vb.) ele almayı ve bunları framework'ün sunduğu araçlar (Guard'lar, Interceptor'lar, Pipe'lar) ve üçüncü taraf kütüphanelerle (Passport.js, Helmet, Rate Limiter) minimize etmeyi kapsar. Ekibimizde, NestJS v10.x ile geliştirdiğimiz mikroservis mimarilerinde güvenlik katmanlarını doğru yapılandırmak, sistemin genel stabilitesi ve veri bütünlüğü için kritik öneme sahiptir. Bu rehber, 2026 yılında geçerli olan en güncel ve sağlam güvenlik pratiklerini sunmaktadır.
## Neden NestJS Güvenliği Önemli?
Uygulama güvenliği, sadece yasal uyumluluk (GDPR, KVKK gibi) için değil, aynı zamanda itibar, müşteri güveni ve finansal istikrar açısından da hayati öneme sahiptir. NestJS gibi modern bir framework ile geliştirilen uygulamalar, genellikle hassas verilerle (kişisel bilgiler, finansal veriler) etkileşim halindedir ve bu da onları siber suçlular için cazip hedefler haline getirir. İşte NestJS güvenliğinin neden bu kadar kritik olduğuna dair somut nedenler:
* **Veri İhlallerini Önleme:** Güvenlik açıkları, hassas verilerin çalınmasına veya kötüye kullanılmasına yol açabilir. 2026 itibarıyla veri ihlallerinin ortalama maliyeti milyonlarca doları bulmaktadır.
* **Yasal ve Düzenleyici Uyum:** Birçok sektörde (finans, sağlık, e-ticaret) katı veri koruma ve gizlilik düzenlemeleri bulunmaktadır. Bu düzenlemelere uyum, yasal sorunlardan kaçınmak için şarttır.
* **İtibar Koruma:** Bir güvenlik ihlali, bir şirketin itibarını kalıcı olarak zedeleyebilir, müşteri kaybına ve pazar payı düşüşüne neden olabilir.
* **Sürekli Hizmet Erişimi:** DDoS gibi saldırılar, uygulamanın hizmet dışı kalmasına neden olarak büyük gelir kayıplarına yol açabilir. Doğru güvenlik önlemleri, bu tür saldırılara karşı direnci artırır.
* **Geliştirici Sorumluluğu:** Geliştiriciler olarak, yazdığımız kodun güvenliğinden sorumluyuz. NestJS'in sağladığı modüler yapı ve güçlü araçlar, güvenli kod yazmayı kolaylaştırır, ancak bu araçların doğru kullanılması gerekir.
* **Kurumsal Kabul:** Büyük ölçekli şirketler ve finans kuruluşları, güvenlik standartları yüksek framework'leri tercih eder. NestJS'in güçlü güvenlik mekanizmaları, kurumsal projelerde tercih edilmesinin ana nedenlerinden biridir.
NestJS'in arkasındaki aktif topluluk ve sürekli güncellemeler (2026 itibarıyla NestJS v10.x ve üzeri sürümler), framework'ün güvenlik açıklarına hızla yanıt vermesini sağlar. Bu da geliştiricilere güncel tehditlere karşı güçlü bir temel sunar. Son projemizde, doğru NestJS güvenlik katmanlarını uygulayarak, dış denetimlerde sıfır kritik güvenlik açığı ile geçmeyi başardık. Bu, framework'ün sunduğu imkanların doğru kullanıldığında ne kadar etkili olabileceğinin bir göstergesidir.
## NestJS Güvenliği vs Diğer Frameworkler (Karşılaştırma)
NestJS, güvenlik mekanizmaları açısından diğer popüler Node.js framework'lerine kıyasla bazı belirgin avantajlar sunar. İşte NestJS'in Express.js ve Fastify gibi alternatiflerle güvenlik odaklı bir karşılaştırması:
| Özellik | NestJS (v10.x, 2026) | Express.js (v4.x, 2026) | Fastify (v4.x, 2026) |
| :------------------ | :--------------------------------------------------- | :-------------------------------------------------------- | :-------------------------------------------------------- |
| **Güvenlik Mimarisi** | Dahili Guard'lar, Interceptor'lar, Pipe'lar ile güçlü ve yapılandırılmış güvenlik katmanları. TypeScript ile tip güvenliği. | Minimalist, güvenlik mekanizmaları genellikle üçüncü taraf middleware'lere bağımlı. | Performans odaklı, güvenlik eklentileriyle genişletilebilir. |
| **Doğrulama (Validation)** | Class-validator ve Class-transformer ile entegre, deklaratif ve güçlü doğrulama. | Genellikle Joi, Express-validator gibi harici kütüphanelerle. | Hızlı JSON Schema tabanlı doğrulama. |
| **Kimlik Doğrulama** | `@nestjs/passport` modülü ile Passport.js entegrasyonu, stratejilerle esnek yapı. | Passport.js veya JWT kütüphaneleriyle manuel entegrasyon. | Genellikle harici kütüphanelerle manuel entegrasyon. |
| **Yetkilendirme** | Guard'lar ve Casl gibi kütüphanelerle RBAC/ABAC uygulaması kolay. | Genellikle manuel middleware yazımı. | Genellikle manuel middleware yazımı. |
| **Güvenlik Middleware** | `@nestjs/platform-express` veya `@nestjs/platform-fastify` aracılığıyla Helmet gibi kütüphanelerin entegrasyonu. | Helmet, CORS gibi middleware'ler manuel olarak eklenir. | Helmet, CORS gibi middleware'ler eklenti olarak eklenir. |
| **Siber Tehditlere Karşı** | OWASP Top 10'a karşı yapılandırılmış çözümler sunar. XSS, CSRF, Rate Limiting için dahili mekanizmalar veya kolay entegrasyon. | Çoğu tehdit için manuel çözüm veya üçüncü taraf kütüphane bağımlılığı. | Performans avantajı sunarken güvenlik için eklenti gereksinimi. |
| **Öğrenme Eğrisi** | Daha yüksek başlangıç eğrisi, ancak tutarlı yapılandırma ile uzun vadede daha güvenli. | Düşük başlangıç eğrisi, ancak güvenlik için daha fazla manuel çaba. | Orta, performans için optimize edilmiş. |
NestJS, mimari yapısı gereği güvenlik odaklı bir geliştirme sürecini teşvik eder. Guard'lar ve Pipe'lar gibi mekanizmalar, güvenlik kontrollerini uygulamanın doğru katmanlarına yerleştirmeyi kolaylaştırır. Bu, özellikle büyük ve karmaşık kurumsal uygulamalarda güvenlik standartlarının tutarlı bir şekilde uygulanmasına olanak tanır. Express.js ve Fastify ise daha minimalist yaklaşımlarıyla esneklik sunarken, güvenlik sorumluluğunu büyük ölçüde geliştiriciye bırakır. Bu da, deneyimsiz ekiplerde güvenlik açıklarına yol açma potansiyelini artırabilir. Kısacası, NestJS güvenlik konusunda "batteries included" (piller dahil) bir yaklaşım sunarken, diğerleri "DIY" (kendin yap) felsefesini benimser.
## NestJS Güvenlik Adımları: Proje Kurulumu ve Temel Yapılandırma
Sıfırdan güvenli bir NestJS uygulaması oluşturmak, sağlam bir temel atmakla başlar. Bu bölümde, NestJS projenizi kuracak ve temel güvenlik katmanlarını yapılandıracaksınız. 2026 itibarıyla NestJS CLI v10.x ve Node.js v20.x LTS sürümünü kullanacağız.
### 1. NestJS CLI Kurulumu
Eğer NestJS CLI kurulu değilse, global olarak kurun:
```bash
npm install -g @nestjs/cli@10.x
```
### 2. Yeni Bir NestJS Projesi Oluşturma
`nestjs-security-2026` adında yeni bir proje oluşturalım:
```bash
nest new nestjs-security-2026
cd nestjs-security-2026
```
Kurulum sırasında `npm` veya `yarn` seçeneği sunulacaktır; `npm`'i seçebilirsiniz.
### 3. Temel Bağımlılıkların Kurulumu
NestJS, birçok güvenlik özelliği için dahili modüller ve popüler kütüphanelerle entegrasyon sağlar. `class-validator` ve `class-transformer` varsayılan olarak gelir, ancak `helmet` ve `rate-limiter` gibi kütüphaneleri manuel olarak kurmak gerekecektir.
```bash
npm install --save @nestjs/platform-express helmet @nestjs/throttler class-validator class-transformer
npm install --save-dev @types/helmet
```
> **Pro Tip:** `helmet` kütüphanesi, çeşitli HTTP başlıklarını ayarlayarak yaygın web güvenlik açıklarına karşı koruma sağlar. `@nestjs/throttler` ise rate limiting için NestJS'e özel bir modüldür.
### 4. `main.ts` Dosyasında Temel Güvenlik Yapılandırması
`src/main.ts` dosyasını açarak `NestFactory.create` metodunda bazı güvenlik ayarlarını etkinleştirelim. Özellikle `ValidationPipe` ve `Helmet` entegrasyonu ilk adımlarımız olacak.
```typescript
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
import helmet from 'helmet'; // ES Modules için doğru import
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// CORS Ayarları: Sadece belirli origin'lere izin ver
app.enableCors({
origin: ['http://localhost:3000', 'https://your-frontend-domain.com'], // 2026'da güvenli domainlerinizi buraya ekleyin
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
credentials: true,
});
// Helmet Middleware: Çeşitli HTTP başlıklarıyla güvenliği artırır
app.use(helmet());
// Global ValidationPipe: Tüm gelen isteklerin otomatik olarak doğrulanmasını sağlar
app.useGlobalPipes(new ValidationPipe({
whitelist: true, // Tanımlanmayan property'leri otomatik olarak kaldırır
forbidNonWhitelisted: true, // Tanımlanmayan property'ler geldiğinde hata fırlatır
transform: true, // Gelen payload'u DTO sınıfına dönüştürür
}));
// CSRF Koruması (Opsiyonel, genellikle cookie tabanlı auth için)
// Bu örnekte JWT kullanacağımız için doğrudan etkinleştirmeyebiliriz.
// Ancak ihtiyaç duyulursa 'csurf' kütüphanesi ile entegre edilebilir.
const port = process.env.PORT || 3001;
await app.listen(port);
console.log(`Application is running on: ${await app.getUrl()} (Port: ${port})`);
}
bootstrap();
```
Bu adımlarla, uygulamanız temel CORS, Helmet ve global input doğrulama güvenlik katmanlarına sahip olacaktır. Bu, NestJS güvenlik yolculuğunuzun sağlam bir başlangıcıdır.
## Temel Güvenlik Uygulamaları ve Örnekler
NestJS'in modüler yapısı, güvenlik özelliklerini kolayca entegre etmemizi sağlar. Bu bölümde, yaygın güvenlik tehditlerine karşı temel koruma mekanizmalarını ve bunların NestJS'te nasıl uygulanacağını pratik örneklerle inceleyeceğiz.
### 1. Giriş Verisi Doğrulama (Input Validation)
**Problem:** Kullanıcıdan gelen verilerin doğrulanmaması, SQL Injection, XSS ve diğer injection saldırılarına yol açabilir. Kötü niyetli veriler, uygulamanın beklenmedik şekillerde davranmasına neden olabilir.
**Çözüm:** `class-validator` ve `class-transformer` kütüphanelerini kullanarak DTO'lar (Data Transfer Objects) aracılığıyla gelen verileri sıkı bir şekilde doğrulayın. `main.ts` dosyasında `ValidationPipe`'ı global olarak etkinleştirdiğimiz için, DTO'larımızı tanımlamamız yeterli olacaktır.
**Kod Örneği:** Bir kullanıcı oluşturma isteği için DTO tanımlayalım.
```typescript
// src/users/dto/create-user.dto.ts
import { IsString, IsEmail, MinLength, MaxLength, IsBoolean, IsOptional } from 'class-validator';
export class CreateUserDto {
@IsString()
@MinLength(3, { message: 'Kullanıcı adı en az 3 karakter olmalı.' })
@MaxLength(50, { message: 'Kullanıcı adı en fazla 50 karakter olmalı.' })
username: string;
@IsEmail({}, { message: 'Geçerli bir e-posta adresi giriniz.' })
email: string;
@IsString()
@MinLength(8, { message: 'Şifre en az 8 karakter olmalı.' })
// Daha karmaşık şifre politikaları için Regex kullanılabilir
password: string;
@IsBoolean()
@IsOptional()
isAdmin?: boolean;
}
```
Ve bu DTO'yu bir controller'da kullanalım:
```typescript
// src/users/users.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Post()
async create(@Body() createUserDto: CreateUserDto) {
// createUserDto otomatik olarak ValidatePipe tarafından doğrulanmıştır.
// Eğer doğrulama başarısız olursa, bir BadRequestException fırlatılır.
return this.usersService.create(createUserDto);
}
}
```
### 2. Çapraz Kaynak İsteği Koruması (CORS - Cross-Origin Resource Sharing)
**Problem:** Web tarayıcıları, güvenlik politikaları gereği farklı bir kaynaktan (domain, protokol, port) gelen isteklere varsayılan olarak izin vermez. Ancak API'lar genellikle farklı frontend uygulamaları tarafından tüketilir. Yanlış yapılandırılmış CORS, XSS veya CSRF saldırılarına yol açabilir.
**Çözüm:** `app.enableCors()` metodunu kullanarak izin verilen `origin`'leri açıkça belirtin. `main.ts` dosyasında bu yapılandırmayı zaten yaptık.
```typescript
// src/main.ts (tekrar gösterim)
// ...
app.enableCors({
origin: ['http://localhost:3000', 'https://your-frontend-domain.com'],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
credentials: true,
});
// ...
```
> **Uyarı:** `origin: '*'` kullanmaktan kaçının. Bu, her kaynaktan gelen isteklere izin verir ve ciddi güvenlik riskleri oluşturur. Her zaman belirli origin'leri listelemelisiniz.
### 3. HTTP Güvenlik Başlıkları (Helmet Entegrasyonu)
**Problem:** Modern web uygulamaları, çeşitli HTTP güvenlik başlıkları aracılığıyla yaygın saldırılara karşı korunabilir. Bu başlıklar eksik olduğunda, XSS, Clickjacking gibi saldırılara zemin hazırlanabilir.
**Çözüm:** `helmet` kütüphanesi, birçok önemli güvenlik başlığını tek bir middleware ile ayarlar. `main.ts` dosyasında `app.use(helmet());` ile bunu zaten entegre ettik.
**Örnek Başlıklar (Helmet tarafından ayarlanan):**
* `X-Content-Type-Options: nosniff`
* `X-Frame-Options: DENY`
* `Strict-Transport-Security: max-age=...` (HTTPS zorunluluğu)
* `X-Powered-By` başlığının kaldırılması (teknoloji ifşa etmeme)
### 4. Hız Sınırlama (Rate Limiting)
**Problem:** Brute-force saldırıları, DDoS (Distributed Denial of Service) saldırıları veya aşırı kaynak tüketimi, uygulamanın yavaşlamasına veya hizmet dışı kalmasına neden olabilir.
**Çözüm:** `@nestjs/throttler` modülünü kullanarak belirli API endpoint'lerine gelen istek sayısını sınırlayın.
**Kurulum:**
```typescript
// src/app.module.ts
import { Module } from '@nestjs/common';
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { APP_GUARD } from '@nestjs/core';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module'; // Varsayalım ki UsersModule var
@Module({
imports: [
ThrottlerModule.forRoot({
ttl: 60, // 60 saniye
limit: 10, // 10 istek
}),
UsersModule,
],
controllers: [AppController],
providers: [
AppService,
{ // Global olarak ThrottlerGuard'ı uygula
provide: APP_GUARD,
useClass: ThrottlerGuard,
},
],
})
export class AppModule {}
```
Bu yapılandırma ile, uygulamanız 60 saniye içinde aynı IP adresinden gelen 10'dan fazla isteği reddedecektir. Belirli endpoint'ler için bu limiti geçersiz kılabilirsiniz:
```typescript
// src/auth/auth.controller.ts (Örnek)
import { Controller, Post, Body } from '@nestjs/common';
import { SkipThrottle, Throttle } from '@nestjs/throttler';
@Controller('auth')
export class AuthController {
@Throttle({ default: { limit: 3, ttl: 60 } }) // Sadece bu endpoint için 60 saniyede 3 istek
@Post('login')
async login(@Body() loginDto: any) {
// ... login logic
return { message: 'Login successful' };
}
@SkipThrottle() // Bu endpoint için hız sınırlamasını atla
@Post('public-data')
async getPublicData() {
return { data: 'This is public data' };
}
}
```
### 5. Hassas Verilerin Şifrelenmesi ve Hashing
**Problem:** Veritabanında şifreler gibi hassas verilerin düz metin olarak saklanması, veri ihlali durumunda ciddi sonuçlar doğurur. Şifrelerin tek yönlü hash'lenmesi ve diğer hassas verilerin şifrelenmesi gereklidir.
**Çözüm:** Şifreler için `bcrypt` gibi güçlü bir hash algoritması kullanın. Diğer hassas veriler için AES-256 gibi simetrik şifreleme algoritmalarını kullanabilirsiniz.
**Kod Örneği (Şifre Hashing):** `bcrypt` kütüphanesini kuralım:
```bash
npm install --save bcrypt
npm install --save-dev @types/bcrypt
```
`UsersService` içinde şifreyi hash'leyelim:
```typescript
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import * as bcrypt from 'bcrypt';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable()
export class UsersService {
private readonly users: any[] = []; // Geçici olarak bellek içi depolama
async create(createUserDto: CreateUserDto): Promise {
const hashedPassword = await bcrypt.hash(createUserDto.password, 10); // 10 salt rounds
const newUser = { ...createUserDto, password: hashedPassword, id: this.users.length + 1 };
this.users.push(newUser);
return newUser;
}
async findOne(username: string): Promise {
return this.users.find(user => user.username === username);
}
async validateUser(username: string, pass: string): Promise {
const user = await this.findOne(username);
if (user && await bcrypt.compare(pass, user.password)) {
const { password, ...result } = user;
return result; // Şifreyi döndürme
}
return null;
}
}
```
## İleri Seviye NestJS Güvenlik Teknikleri
Uygulamanız büyüdükçe ve daha karmaşık hale geldikçe, temel güvenlik önlemleri yeterli olmayabilir. Bu bölümde, NestJS'te ileri seviye güvenlik tekniklerini ve production ortamında kullanılabilecek stratejileri ele alacağız.
### 1. Kimlik Doğrulama (Authentication) ve Yetkilendirme (Authorization) ile JWT
**Problem:** Kullanıcıların kimliğini doğrulamak ve belirli kaynaklara erişim yetkilerini kontrol etmek, modern uygulamaların temel güvenlik gereksinimlerindendir. Yanlış yapılandırılmış kimlik doğrulama, yetkisiz erişime yol açabilir.
**Çözüm:** JWT (JSON Web Token) tabanlı kimlik doğrulama ve NestJS'in `@nestjs/passport` modülü ile yetkilendirme Guard'ları kullanın.
**Kurulum:**
```bash
npm install --save @nestjs/passport passport passport-jwt @nestjs/jwt
npm install --save-dev @types/passport-jwt
```
**`AuthModule` Oluşturma:**
```typescript
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { JwtStrategy } from './jwt.strategy';
import { ConfigModule, ConfigService } from '@nestjs/config'; // Ortam değişkenleri için
@Module({
imports: [
UsersModule,
PassportModule,
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get('JWT_SECRET'),
signOptions: { expiresIn: '60s' }, // 2026'da kısa ömürlü token'lar daha güvenli kabul edilir
}),
inject: [ConfigService],
}),
ConfigModule,
],
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
exports: [AuthService],
})
export class AuthModule {}
```
**`jwt.strategy.ts`:**
```typescript
// src/auth/jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private configService: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: configService.get('JWT_SECRET'),
});
}
async validate(payload: any) {
// Payload'dan gelen bilgileri kullanarak kullanıcıyı doğrula
// Bu bilgiler genellikle kullanıcının ID'si veya rolüdür.
return { userId: payload.sub, username: payload.username, roles: payload.roles };
}
}
```
**`auth.service.ts`:**
```typescript
// src/auth/auth.service.ts
import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(
private usersService: UsersService,
private jwtService: JwtService,
) {}
async validateUser(username: string, pass: string): Promise {
const user = await this.usersService.findOne(username);
if (user && await this.usersService.validateUser(username, pass)) { // Şifre karşılaştırması UsersService'de yapılıyor
const { password, ...result } = user;
return result;
}
return null;
}
async login(user: any) {
const payload = { username: user.username, sub: user.id, roles: user.roles };
return {
access_token: this.jwtService.sign(payload),
};
}
}
```
**`auth.controller.ts`:**
```typescript
// src/auth/auth.controller.ts
import { Controller, Post, Body, UseGuards, Request, Get } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './local-auth.guard'; // Local stratejisi için
import { JwtAuthGuard } from './jwt-auth.guard'; // JWT stratejisi için
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
@UseGuards(LocalAuthGuard)
@Post('login')
async login(@Request() req) {
return this.authService.login(req.user);
}
@UseGuards(JwtAuthGuard)
@Get('profile')
getProfile(@Request() req) {
return req.user; // JWT payload'ından gelen kullanıcı bilgisi
}
}
```
`LocalAuthGuard` ve `JwtAuthGuard` dosyalarını da oluşturmanız gerekecektir. Bu Guard'lar, Passport stratejilerini sarmalar ve NestJS'in Guard arayüzüne uyar.
```typescript
// src/auth/local-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
// src/auth/jwt-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
```
Ve `local.strategy.ts` (kullanıcı adı/şifre ile login için):
```bash
npm install --save passport-local
npm install --save-dev @types/passport-local
```
```typescript
// src/auth/local.strategy.ts
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super();
}
async validate(username: string, password: string): Promise {
const user = await this.authService.validateUser(username, password);
if (!user) {
throw new UnauthorizedException('Kullanıcı adı veya şifre yanlış.');
}
return user; // Kullanıcı nesnesini döndür, şifre hariç
}
}
```
`AuthModule`'a `LocalStrategy`'yi de eklemeyi unutmayın:
```typescript
// src/auth/auth.module.ts (güncellenmiş)
// ...
import { LocalStrategy } from './local.strategy';
@Module({
// ...
providers: [AuthService, JwtStrategy, LocalStrategy],
// ...
})
export class AuthModule {}
```
### 2. Rol Tabanlı Erişim Kontrolü (RBAC - Role-Based Access Control)
**Problem:** Uygulamanızdaki farklı kullanıcı türlerinin (yönetici, kullanıcı, editör) belirli kaynaklara veya işlevlere erişimini kısıtlamak gerekir. Manuel kontrol, hata yapmaya açık ve yönetimi zor olabilir.
**Çözüm:** Custom Guard'lar ve Decorator'lar kullanarak RBAC uygulayın. Bu, yetkilendirme mantığını merkezi bir yerde tutmanızı sağlar.
**Kod Örneği:** `RolesGuard` ve `Roles` decorator'ı oluşturalım.
```typescript
// src/auth/roles.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
// src/auth/roles.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride('roles', [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles) {
return true; // Rol gereksinimi yoksa erişime izin ver
}
const { user } = context.switchToHttp().getRequest();
// Kullanıcının rolleri, JWT payload'ından gelmeli (JwtStrategy'de ayarlandı)
return requiredRoles.some((role) => user.roles?.includes(role));
}
}
```
Controller'da kullanımı:
```typescript
// src/users/users.controller.ts (Güncellenmiş)
import { Controller, Post, Body, Get, UseGuards } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UsersService } from './users.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { RolesGuard } from '../auth/roles.guard';
import { Roles } from '../auth/roles.decorator';
@Controller('users')
@UseGuards(JwtAuthGuard, RolesGuard) // Önce kimlik doğrulama, sonra yetkilendirme
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Post()
@Roles('admin') // Sadece 'admin' rolüne sahip kullanıcılar bu endpoint'i kullanabilir
async create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
@Get()
@Roles('admin', 'editor') // 'admin' veya 'editor' rolüne sahip kullanıcılar
async findAll() {
return this.usersService.findAll();
}
@Get(':id')
@Roles('admin', 'user') // 'admin' veya kendi verisine erişen 'user'
async findOne(@Param('id') id: string) {
// Ek kontrol: user.id === id veya user.roles.includes('admin')
return this.usersService.findOne(id);
}
}
```
> **Experience:** Production ortamında RBAC uygularken, rollerin veritabanında dinamik olarak yönetilmesi ve yetkilendirme mantığının daha karmaşık senaryolar (ABAC - Attribute-Based Access Control) için Casl gibi kütüphanelerle genişletilmesi gerekebilir. Bu, özellikle mikroservis mimarilerinde yetkilendirme kararlarını merkezi hale getirmek için önemlidir.
### 3. Veri Şifreleme ve Kriptografi Entegrasyonu
**Problem:** Özellikle hassas kişisel veriler veya finansal bilgiler gibi verilerin, depolama veya iletim sırasında yetkisiz erişime karşı korunması gerekir. Veritabanı ihlali durumunda bile verilerin okunamaz kalması önemlidir.
**Çözüm:** Node.js'in dahili `crypto` modülünü veya `libsodium-wrappers` gibi güçlü kriptografi kütüphanelerini kullanarak verileri şifreleyin ve şifresini çözün.
**Kod Örneği (AES-256 GCM ile simetrik şifreleme):**
```typescript
// src/common/encryption.service.ts
import { Injectable } from '@nestjs/common';
import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class EncryptionService {
private readonly algorithm = 'aes-256-gcm';
private readonly key: Buffer;
constructor(private configService: ConfigService) {
const secret = this.configService.get('ENCRYPTION_SECRET');
if (!secret || secret.length < 32) { // 2026'da en az 32 karakterlik bir secret önerilir
throw new Error('ENCRYPTION_SECRET ortam değişkeni ayarlanmamış veya çok kısa.');
}
this.key = scryptSync(secret, 'salt', 32); // Güvenli anahtar türetme
}
encrypt(text: string): string {
const iv = randomBytes(16); // Initialization Vector
const cipher = createCipheriv(this.algorithm, this.key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
const tag = cipher.getAuthTag().toString('hex');
return `${iv.toString('hex')}:${encrypted}:${tag}`;
}
decrypt(encryptedText: string): string {
const [ivHex, encryptedHex, tagHex] = encryptedText.split(':');
const iv = Buffer.from(ivHex, 'hex');
const encrypted = Buffer.from(encryptedHex, 'hex');
const tag = Buffer.from(tagHex, 'hex');
const decipher = createDecipheriv(this.algorithm, this.key, iv);
decipher.setAuthTag(tag);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
}
```
Bu servisi bir modüle ekleyip kullanabilirsiniz. Örneğin, `UsersService`'de bir kullanıcının hassas bilgilerini (örneğin, telefon numarası) şifrelemek için:
```typescript
// src/users/users.service.ts (Güncellenmiş)
// ...
import { EncryptionService } from '../common/encryption.service';
@Injectable()
export class UsersService {
// ...
constructor(
// ...
private encryptionService: EncryptionService,
) {}
async create(createUserDto: CreateUserDto): Promise {
// ...
const encryptedPhoneNumber = this.encryptionService.encrypt(createUserDto.phoneNumber);
const newUser = { ...createUserDto, password: hashedPassword, phoneNumber: encryptedPhoneNumber };
// ...
return newUser;
}
// ...
}
```
## Güven