Belajar NestJS - Security & Authentication
Episode 12 of 24

Belajar NestJS - Security & Authentication

Episode ini membahas keamanan API NestJS: fundamentals security, autentikasi JWT dan guards, integrasi Passport dengan auth strategies, serta role-based access control dan permissions berbasis role.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

API tanpa autentikasi adalah pintu terbuka. Episode 12 membangun lapisan keamanan pertama yang wajib ada: autentikasi dengan JWT, integrasi Passport, dan otorisasi berbasis role. Kalian akan belajar melindungi endpoint agar hanya bisa diakses pengguna yang terautentikasi dengan peran yang tepat.

Fundamentals Keamanan NestJS

Prinsip Dasar

Sebelum masuk kode, pahami prinsip keamanan yang mendasarinya:

  • Jangan pernah percaya input — validasi selalu.
  • Jangan pernah menyimpan password plain text — gunakan hash.
  • Terapkan least privilege — beri akses minimal yang diperlukan.
  • Selalu gunakan HTTPS di production.

NestJS memberi struktur yang rapi untuk menerapkan semua prinsip ini lewat guards dan strategy.

Hash Password dengan bcrypt

Install bcrypt dan @nestjs/jwt
npm install bcrypt @nestjs/jwt
JSMeng-hash password dengan bcrypt
import * as bcrypt from "bcrypt";
 
export async function hashPassword(password: string): Promise<string> {
  const salt = await bcrypt.genSalt(10);
  return bcrypt.hash(password, salt);
}

bcrypt.hash menghasilkan hash yang aman dengan salt acak — install dulu dengan npm install bcrypt @nestjs/jwt. Jangan pernah menyimpan password mentah di database.

Autentikasi JWT

Apa itu JWT

JSON Web Token (JWT) adalah token yang membawa klaim terenkripsi — biasanya identitas user dan waktu kedaluwarsa. Token ini ditandatangani server sehingga bisa diverifikasi tanpa menyimpan session di server.

Membuat Token di AuthService

JSAuthService untuk sign JWT
@Injectable()
export class AuthService {
  constructor(private readonly jwtService: JwtService) {}
 
  async login(user: { id: number; username: string }): Promise<{ accessToken: string }> {
    const payload = { sub: user.id, username: user.username };
    return {
      accessToken: await this.jwtService.signAsync(payload),
    };
  }
}

signAsync membuat token yang berisi payload user. Token ini dikirim klien dan dipakai pada request berikutnya.

Guards dan Passport Integration

Apa itu Guard

Guard menentukan apakah request boleh dilanjutkan. Guard autentikasi memeriksa token pada request, sedangkan guard otorisasi memeriksa peran pengguna.

Membuat JwtAuthGuard

Guard membaca token dari header Authorization, memverifikasinya dengan JwtService, lalu menyimpan payload ke request.user:

JSGuard autentikasi JWT
@Injectable()
export class JwtAuthGuard implements CanActivate {
  constructor(private readonly jwtService: JwtService) {}
 
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest<Request>();
    const auth = request.headers.authorization;
    const token = auth?.startsWith("Bearer ") ? auth.split(" ")[1] : undefined;
 
    if (!token) {
      throw new UnauthorizedException("Token tidak ditemukan");
    }
 
    try {
      request.user = await this.jwtService.verifyAsync(token);
    } catch {
      throw new UnauthorizedException("Token tidak valid");
    }
 
    return true;
  }
}

Guard memvalidasi token dari header Authorization dan menyimpan payload ke request.user.

Passport Strategy

NestJS juga mendukung Passport — library autentikasi populer. Dengan @nestjs/passport dan passport-jwt:

Install Passport JWT
npm install @nestjs/passport passport passport-jwt
npm install -D @types/passport-jwt
JSPassport JWT strategy
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: process.env.JWT_SECRET ?? "rahasia",
    });
  }
 
  async validate(payload: { sub: number; username: string }) {
    return { userId: payload.sub, username: payload.username };
  }
}

Role-Based Access Control

Membuat Roles Decorator dan RolesGuard

Untuk membatasi akses per peran, buat decorator kustom bersama guard pembacanya:

JSDekorator @Roles dan RolesGuard
export const ROLES_KEY = "roles";
export const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);
 
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}
 
  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}

Memakai Roles di Controller

JSEndpoint yang dilindungi role
@Controller("admin")
@UseGuards(RolesGuard)
export class AdminController {
  @Get("reports")
  @Roles("admin")
  getReports(): string {
    return "Laporan rahasia";
  }
}

Penutup

Episode 12 membangun fondasi keamanan yang solid. Inti yang harus dibawa pulang:

  • Password selalu di-hash dengan bcrypt, jangan pernah plain text.
  • JWT membawa klaim user dan ditandatangani server.
  • Guard memvalidasi token dan menyimpan user ke request.user.
  • @Roles dan RolesGuard menerapkan otorisasi berbasis peran.
  • Gunakan Reflector untuk membaca metadata dekorator.
Belajar NestJS - Security & Authentication | Belajar NestJS