project/NestJS + Prisma로 만드는 웹 애플리케이션 첫걸음 - 쇼핑몰

📌 NestJS + Prisma + Next.js로 만드는 웹 애플리케이션 첫걸음 - 애자일 쇼핑몰 프로젝트 - 보안 강화 및 데이터 보호 전략

octo54 2025. 3. 20. 11:13
반응형

📌 NestJS + Prisma + Next.js로 만드는 웹 애플리케이션 첫걸음 - 애자일 쇼핑몰 프로젝트 - 보안 강화 및 데이터 보호 전략

1. 웹 애플리케이션 보안의 중요성

쇼핑몰 애플리케이션에서는 사용자 정보, 결제 데이터, 주문 기록 등 민감한 데이터가 포함됩니다.
보안이 취약할 경우 개인정보 유출, 결제 사기, 서비스 장애 등의 심각한 문제가 발생할 수 있습니다.

이 챕터에서 다룰 보안 강화 방법:

  • API 인증 및 JWT 보안 적용
  • CSRF/XSS 방어 및 보안 헤더 설정
  • 데이터 암호화 및 안전한 저장 방식
  • SQL Injection 및 보안 로깅

💡 이제 Next.js + NestJS 기반 쇼핑몰의 보안을 강화하는 방법을 살펴보겠습니다.


2. API 보안 강화 - JWT 인증 및 보호

2.1. JWT 기반 API 인증 적용

반응형

JWT(JSON Web Token)를 활용하여 API 요청 시 사용자 인증을 확인합니다.

💡 JWT 토큰 생성 (auth.service.ts)

import * as jwt from 'jsonwebtoken';

export class AuthService {
  async generateToken(user) {
    return jwt.sign(
      { id: user.id, email: user.email, role: user.role },
      process.env.JWT_SECRET,
      { expiresIn: '1h' }
    );
  }
}

💡 NestJS API 요청 시 JWT 검증 (auth.guard.ts)

import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';
import * as jwt from 'jsonwebtoken';

@Injectable()
export class JwtAuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const token = request.headers.authorization?.split(' ')[1];

    if (!token) throw new UnauthorizedException('토큰이 필요합니다.');

    try {
      request.user = jwt.verify(token, process.env.JWT_SECRET);
      return true;
    } catch (error) {
      throw new UnauthorizedException('유효하지 않은 토큰입니다.');
    }
  }
}

이제 API 호출 시 JWT가 필요하며, 인증된 사용자만 접근 가능합니다.


3. CSRF/XSS 공격 방어 및 보안 헤더 설정

3.1. CSRF(Cross-Site Request Forgery) 방어

CSRF 공격을 방어하기 위해 SameSite 쿠키 정책을 적용합니다.

💡 NextAuth.js에서 CSRF 방어 설정 (pages/api/auth/[...nextauth].ts)

export default NextAuth({
  session: { strategy: 'jwt' },
  cookies: {
    sessionToken: {
      name: 'next-auth.session-token',
      options: { httpOnly: true, secure: true, sameSite: 'lax' },
    },
  },
});

이제 다른 사이트에서 악성 요청을 보낼 수 없습니다.


3.2. XSS(Cross-Site Scripting) 공격 방어

XSS 공격을 방어하기 위해 사용자의 입력을 필터링해야 합니다.

💡 입력값 필터링 (utils/sanitize.ts)

import DOMPurify from 'dompurify';

export function sanitize(input: string) {
  return DOMPurify.sanitize(input);
}

이제 사용자 입력을 처리할 때 자동으로 XSS 공격을 방지할 수 있습니다.


3.3. 보안 헤더 설정 (Helmet 적용)

웹 애플리케이션의 보안을 강화하려면 Helmet을 활용하여 보안 헤더를 설정할 수 있습니다.

💡 NestJS에 Helmet 적용 (main.ts)

import helmet from 'helmet';

app.use(helmet());

이제 HTTP 보안 헤더가 자동으로 설정됩니다.


4. 데이터 암호화 및 안전한 저장 방식

4.1. 비밀번호 암호화 (bcrypt 사용)

사용자의 비밀번호는 반드시 해싱하여 저장해야 합니다.

💡 비밀번호 해싱 및 검증 (auth.service.ts)

import * as bcrypt from 'bcrypt';

export class AuthService {
  async hashPassword(password: string) {
    return await bcrypt.hash(password, 10);
  }

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

이제 비밀번호가 안전하게 저장됩니다.


4.2. 결제 정보 보안 (카드 정보 암호화)

Stripe 등 결제 시스템을 사용할 경우, 민감한 카드 정보는 직접 저장하지 않고 토큰화(Tokenization) 방식을 사용해야 합니다.

💡 Stripe를 사용하여 결제 정보 보호 (stripe.service.ts)

const paymentIntent = await stripe.paymentIntents.create({
  amount: 5000,
  currency: 'usd',
  payment_method_types: ['card'],
});

이제 카드 정보는 Stripe에서 관리하며, 직접 저장하지 않습니다.


5. SQL Injection 및 보안 로깅 적용

5.1. SQL Injection 방어 (Prisma ORM 활용)

SQL Injection 공격을 방어하기 위해 ORM(Prisma)에서 안전한 쿼리를 사용해야 합니다.

💡 Prisma에서 안전한 쿼리 사용 (users.service.ts)

async getUserByEmail(email: string) {
  return this.prisma.user.findUnique({
    where: { email },
  });
}

이제 쿼리 문자열을 직접 입력하는 방식이 아닌 안전한 ORM 방식이 적용되었습니다.


5.2. 보안 이벤트 로깅 적용

보안 이벤트(로그인 시도, 관리자 활동 등)를 로깅하여 이상 징후 감지가 가능해야 합니다.

💡 NestJS 로깅 설정 (logger.middleware.ts)

import { Logger, NestMiddleware } from '@nestjs/common';

export class LoggerMiddleware implements NestMiddleware {
  private logger = new Logger('Security');

  use(req: Request, res: Response, next: Function) {
    this.logger.log(`요청: ${req.method} ${req.url}`);
    next();
  }
}

이제 보안 로그를 기록하여 이상 요청을 감지할 수 있습니다.


6. 보안 강화를 위한 추가 조치

HTTPS 적용: 모든 요청은 HTTPS를 통해 암호화
CORS 설정 강화: 허용된 도메인에서만 API 호출 가능
Rate Limiting 적용: 과도한 요청을 방지하여 서버 보호
2FA(이중 인증) 적용: 관리자 계정의 추가 보안 강화

💡 이러한 보안 조치를 통해 쇼핑몰 애플리케이션의 안전성을 극대화할 수 있습니다.


🎯 마무리하며

이번 챕터에서는 쇼핑몰 애플리케이션의 보안을 강화하는 다양한 방법을 다뤘습니다.

  • API 보안 강화 → JWT 인증 적용
  • 웹 보안 적용 → CSRF/XSS 방어, 보안 헤더 설정
  • 데이터 보호 → 비밀번호 암호화, 결제 정보 보안
  • SQL Injection 방어 및 로깅 적용

다음 단계에서는 7.1. CI/CD 자동 배포 환경 구축을 다룰 예정입니다. 🚀