Menu
CoddyTech

가드

Coddy Node.js 여정의 TypeScript와 NestJS 섹션에 포함된 레슨. 24개 중 18번째.

누구나 작업을 만들거나 삭제할 수 있습니다. 가드는 요청이 핸들러에 도달해도 되는지 결정합니다. Nest는 가드의 canActivate를 호출하고, 이 메서드가 false를 반환하면 메서드를 실행하지 않고 403 Forbidden을 응답합니다.

@Injectable()
export class OpenHoursGuard implements CanActivate {
    canActivate(context: ExecutionContext): boolean {
        const hour = new Date().getHours();
        return hour >= 9 && hour < 17;
    }
}

@Post()
@UseGuards(OpenHoursGuard)
book() {}

context.switchToHttp().getRequest()는 요청을 가져옵니다. Node는 헤더 이름을 소문자로 저장하므로 request.headers['x-api-key']를 읽으세요. 메서드에 지정한 @UseGuards는 해당 메서드를 보호합니다. 컨트롤러 클래스에 지정하면 그 안의 모든 메서드를 보호합니다.

challenge icon

챌린지

쉬움

현재 누구나 작업을 만들거나 삭제할 수 있습니다. 데이터를 변경하는 두 경로에 API 키를 요구하도록 잠그세요. API 키는 클라이언트가 요청 헤더에 보내는 비밀 값입니다. 읽기는 누구에게나 계속 허용됩니다.

  1. src/common/api-key.guard.ts를 여세요. ApiKeyGuard의 canActivate 메서드에서 요청의 x-api-key 헤더를 읽으세요. context.switchToHttp().getRequest()를 사용하면 요청을 가져올 수 있고, 헤더 이름은 항상 소문자입니다.
  2. 해당 헤더의 값이 process.env.API_KEY와 일치할 때만 true를 반환하세요. 이 강의에서는 tasks-key-123을 값으로 설정합니다. 헤더가 없는 경우를 포함해 그 외 모든 경우에는 false를 반환하세요. 가드가 false를 반환하면 Nest는 403으로 응답하고 경로의 메서드를 실행하지 않습니다.
  3. src/tasks/tasks.controller.ts에서 ../common/api-key.guard로부터 ApiKeyGuard를, @nestjs/common으로부터 UseGuards를 가져오세요. create 메서드(POST /tasks)와 remove 메서드(DELETE /tasks/:id)에 @UseGuards(ApiKeyGuard)를 추가하세요. 클래스에는 추가하지 마세요. 그러면 GET 경로도 잠기게 됩니다.
  4. GET /tasks, GET /tasks/:id, GET /stats는 키 없이 계속 사용할 수 있습니다.

테스트해 보세요: 헤더 없이 { "title": "Buy milk" }를 /tasks로 POST하세요. 403 응답을 받습니다.

{ "message": "Forbidden resource", "error": "Forbidden", "statusCode": 403 }

요청 표시줄의 Headers 필드를 열고 x-api-key: tasks-key-123 행을 추가한 다음 POST를 다시 보내세요. 201 응답과 새 작업을 받습니다. x-api-key: guess를 사용하면 403 응답을 받습니다. DELETE /tasks/4에도 키가 필요합니다. 키가 없으면 403, 키가 있으면 204 응답을 받습니다. GET /tasks는 헤더가 전혀 없어도 작동합니다.

직접 해보기

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';

@Injectable()
export class ApiKeyGuard implements CanActivate {
    canActivate(context: ExecutionContext): boolean {
        // 요청의 x-api-key 헤더가
        // process.env.API_KEY와 일치할 때만 요청을 통과시킵니다.
        return true;
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

TypeScript와 NestJS의 모든 레슨

직접 연습해 보세요: Express 플레이그라운드