NestJS JWT Guard를 사용하여 PlayaMXCRM의 iCal 엔드포인트 보안 강화하기
요약
NestJS의 JWT Guard를 사용하여 PlayaMXCRM의 iCal 엔드포인트 보안을 강화하는 방법을 다룹니다. 인증되지 않은 접근을 차단하기 위해 전용 Guard를 생성하고 컨트롤러에 적용하여 보안을 중앙 집중화했습니다.
핵심 포인트
- JWT Guard를 통한 iCal 엔드포인트의 인증 로직 중앙 집중화
- 미들웨어 방식의 중복 로직 문제를 Guard 적용으로 해결
- 유효하지 않은 JWT 요청에 대해 403 Forbidden 응답 처리
- 보안 강화 및 불필요한 API 경로 정리를 통한 코드 품질 개선
NestJS JWT Guard를 사용하여 PlayaMXCRM의 iCal 엔드포인트 보안 강화하기
요약 (TL;DR): iCal 컨트롤러에 JWT Guard를 추가하고, 컨트롤러가 해당 Guard를 사용하도록 업데이트했으며, 더 이상 사용되지 않는 API 경로를 제거했습니다. 이를 통해 캘린더 데이터에 대한 인증되지 않은 요청을 차단하고, 재사용 가능한 Guard에 인증 로직을 중앙 집중화했습니다.
문제점
우리 API의 /ical 엔드포인트는 어떠한 인증 확인 절차 없이 노출되어 있었습니다. URL을 아는 사람이라면 누구나 해당 엔드포인트에 접근하여 캘린더 이벤트를 가져올 수 있었으며, 이는 잠재적으로 민감한 데이터의 노출로 이어질 수 있었습니다. 문제는 명확했습니다: Authorization 헤더 검증이 없었고, 속도 제한 (Rate Limiting)도 없었으며, 감사 추적 (Audit Trail)도 없었습니다. 운영 환경(Production)에서 이는 내부 캘린더 데이터가 외부 당사자에게 유출될 수 있음을 의미했습니다.
GET /ical?start=2026-07-01&end=2026-07-31
↳ 200 OK
↳ 전체 iCal 피드 반환
Guard가 없었을 때, 변경 전의 컨트롤러는 다음과 같았습니다:
// apps/api/src/ical/ical.controller.ts
import { Controller, Get, Param, Query, Res } from "@nestjs/common";
import type { Response } from "express";
...
인증이나 검증이 전혀 없다는 점에 주목하십시오.
처음 시도했던 방법
저의 첫 번째 시도는 경로 전체에 간단한 미들웨어 (Middleware)를 뿌리는 것이었습니다:
app.use("/ical", (req, res, next) => {
const auth = req.headers.authorization;
if (!auth) return res.status(401).send("Unauthorized");
...
작동은 했지만, 컨트롤러 전반에 로직이 중복되었고 코드베이스를 유지 관리하기 어렵게 만들었습니다. 또한 전역 가드 (Global Guard)를 추가하는 것도 시도해 보았으나, 이는 /ical뿐만 아니라 모든 엔드포인트에 영향을 미치게 됩니다. 저에게는 더 세밀한 (Fine-grained) 해결책이 필요했습니다.
구현
1. JWT Guard 생성
JWT를 디코딩하고 페이로드 (Payload)를 req.user에 부착하는 전용 Guard를 생성했습니다. 이는 jsonwebtoken 라이브러리와 공유 비밀키 (Shared Secret)를 사용합니다.
// apps/api/src/common/guards/jwt.guard.ts
import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
import { verify } from "jsonwebtoken";
...
2. iCal 컨트롤러에 Guard 적용
컨트롤러를 업데이트하여 UseGuards를 임포트하고 해당 라우트에 JwtGuard를 적용했습니다. 컨트롤러의 모습은 다음과 같습니다:
// apps/api/src/ical/ical.controller.ts
-import { Controller, Get, Param, Query, Res } from "@nestjs/common";
+import { Controller, Get, Param, Query, Res, UseGuards } from "@nestjs/common";
...
이제 /ical로 들어오는 모든 요청은 유효한 JWT를 포함해야 합니다. 가드 (Guard)는 유효하지 않은 요청을 자동으로 403 상태 코드로 거부합니다.
3. API 클라이언트 정리
컨트롤러를 리팩토링(Refactoring)하는 동안, api.ts 파일에 더 이상 사용되지 않는 중복된 print 엔드포인트가 있다는 것을 발견했습니다. 데드 코드 (Dead code)를 제거하면 유지보수성이 향상되고 공격 표면 (Surface area)을 줄일 수 있습니다.
diff
// apps/web/src/lib/api.ts
...
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기