NestJS는 효율적이고 확장 가능한 Node.js 웹 애플리케이션을 구축하기 위한 프로그레시브 프레임워크입니다. 이 프레임워크는 TypeScript로 작성되었으며, 모듈화된 아키텍처를 통해 코드의 재사용성과 유지보수성을 높입니다. NestJS는 Angular에서 영감을 받아 구조적으로 유사한 점이 많으며, Express.js와 Fastify를 기본적으로 지원합니다13.
주요 특징
1. 모듈화된 아키텍처
NestJS는 애플리케이션을 모듈 단위로 나누어 관리합니다. 각 모듈은 특정 기능을 담당하며, 모듈 간의 의존성을 통해 애플리케이션을 구성합니다. 이러한 구조는 코드의 재사용성을 높이고 유지보수를 용이하게 합니다2.
2. TypeScript 지원
NestJS는 TypeScript를 기본으로 사용하여 강력한 타입 시스템을 제공합니다. 이는 코드의 안정성과 가독성을 높이며, 개발 단계에서 발생할 수 있는 오류를 줄여줍니다1.
3. 의존성 주입 (Dependency Injection)
NestJS는 의존성 주입을 통해 객체 간의 의존성을 관리합니다. 이를 통해 코드의 결합도를 낮추고 테스트 가능성을 높입니다2.
4. 다양한 기능 내장
NestJS는 HTTP 요청 및 응답 처리, 미들웨어, 가드, 예외 필터, 로깅 등 서버 동작에 필수적인 기능을 기본으로 포함하고 있습니다. 이를 통해 개발자는 필요한 기능을 쉽게 구현할 수 있습니다3.
5. Express.js 및 Fastify 지원
NestJS는 Express.js와 Fastify를 래핑하여 동작합니다. 기본적으로 Express.js를 사용하지만, Fastify로 쉽게 전환할 수 있습니다. 이를 통해 개발자는 자신에게 맞는 HTTP 서버를 선택할 수 있습니다6.
설치 및 시작하기
1. Nest CLI 설치
NestJS 프로젝트를 생성하기 위해서는 Nest CLI를 설치해야 합니다.
npm i -g @nestjs/cli
2. 프로젝트 생성
Nest CLI를 사용하여 새로운 프로젝트를 생성합니다.
nest new project-name
3. 프로젝트 구조
생성된 프로젝트는 다음과 같은 구조를 가집니다:
- src: 애플리케이션 소스 코드
- app.controller.ts: 컨트롤러 구현
- app.service.ts: 비즈니스 로직 구현
- app.module.ts: 모듈 설정
- main.ts: 애플리케이션 부트스트랩 코드
4. 서버 실행
프로젝트 디렉토리로 이동한 후, 다음 명령어로 서버를 실행합니다.
npm run start:dev
결론
NestJS는 모듈화된 아키텍처와 TypeScript 지원을 통해 효율적이고 확장 가능한 서버 사이드 애플리케이션을 구축할 수 있는 강력한 프레임워크입니다. 다양한 내장 기능과 Express.js 및 Fastify 지원을 통해 개발자는 자신에게 맞는 환경을 선택하여 개발을 진행할 수 있습니다.
Citations: 1 https://nestjs.com2 https://namu.wiki/w/NestJS[3](https://www.elancer.co.kr/blog/view?seq=197) https://www.elancer.co.kr/blog/view?seq=197[4](https://velog.io/%40kisuk623/Nest.js의-기본과-시작) https://velog.io/%40kisuk623/Nest.js의-기본과-시작5 https://goldenrabbit.co.kr/2023/06/05/nestjs/[6](https://wikidocs.net/147787) https://wikidocs.net/147787[7](https://docs.nestjs.com/) https://docs.nestjs.com [8] https://www.youtube.com/watch?v=0M8AYU_hPas [9] https://docs.nestjs.com/first-steps [10] https://www.youtube.com/watch?v=8_X0nSrzrCw [11] https://courses.nestjs.com [12] https://dev.to/nandhakumar/nest-js-part-1-creating-your-first-api-5f2a [13] https://www.youtube.com/watch?v=sFnAHC9lLaw [14] https://www.javatpoint.com/nestjs
NestJS와 Express.js의 차이점은
NestJS와 Express.js는 둘 다 Node.js 기반의 웹 애플리케이션 프레임워크이지만, 그 구조와 철학에서 큰 차이점을 가지고 있습니다. 아래는 두 프레임워크의 주요 차이점을 정리한 내용입니다.
주요 차이점
1. 아키텍처 및 철학
- Express.js: Express는 "비의존적(unopinionated)" 프레임워크로, 개발자에게 많은 자유를 제공합니다. 이는 개발자가 자신의 필요에 맞게 코드를 구현할 수 있도록 유연성을 제공하지만, 큰 프로젝트에서는 구조적 복잡성을 초래할 수 있습니다[1][4].
- NestJS: Nest는 "의존적(opinionated)" 프레임워크로, Angular에서 영감을 받아 모듈, 컨트롤러, 프로바이더 등의 구조를 따릅니다. 이는 코드의 일관성과 유지보수성을 높이며, 대규모 애플리케이션에 적합합니다[2][4].
2. 언어 및 타입 시스템
- Express.js: 주로 JavaScript로 작성되며, TypeScript를 선택적으로 사용할 수 있습니다. 이는 JavaScript에 익숙한 개발자에게 친숙합니다[1][2].
- NestJS: 기본적으로 TypeScript를 사용하여 강력한 타입 시스템을 제공합니다. 이는 코드의 안정성과 가독성을 높이며, 개발 단계에서 발생할 수 있는 오류를 줄여줍니다[1][2][6].
3. 모듈화 및 확장성
- Express.js: 미들웨어와 라우팅을 통해 기능을 확장할 수 있으며, 다양한 서드파티 모듈을 쉽게 통합할 수 있습니다. 그러나 구조적 지침이 부족하여 대규모 프로젝트에서는 관리가 어려울 수 있습니다[1][3][11].
- NestJS: 모듈화된 아키텍처를 통해 애플리케이션을 구성하며, 각 모듈은 특정 기능을 담당합니다. 이는 코드의 재사용성과 유지보수성을 높이며, 대규모 애플리케이션에 적합합니다[2][6][7].
4. 비동기 처리
- Express.js: 비동기 함수(async/await)를 지원하지만, 기본적으로 콜백 기반의 비동기 처리를 사용합니다. 이는 콜백 헬(callback hell)을 초래할 수 있습니다[1][4].
- NestJS: 비동기 함수(async/await)를 기본적으로 지원하며, 비동기 처리를 더 쉽게 관리할 수 있습니다[1][2].
5. 내장 기능 및 확장성
- Express.js: 라우팅, 미들웨어, 템플릿 엔진, 에러 핸들링 등 다양한 기능을 제공하며, 필요한 기능을 서드파티 모듈로 확장할 수 있습니다[11][12][13].
- NestJS: 내장된 모듈 시스템을 통해 다양한 기능을 제공하며, GraphQL, WebSockets, 마이크로서비스 등 다양한 기술을 쉽게 통합할 수 있습니다[6][7][8].
6. 커뮤니티 및 생태계
- Express.js: 오랜 역사를 가지고 있으며, 큰 커뮤니티와 풍부한 서드파티 모듈 생태계를 자랑합니다. 이는 다양한 문제에 대한 해결책을 쉽게 찾을 수 있게 합니다[1][4][13].
- NestJS: 비교적 새로운 프레임워크이지만, 빠르게 성장하는 커뮤니티와 활발한 개발 활동을 가지고 있습니다. TypeScript와의 통합 덕분에 최신 JavaScript 생태계와 잘 어울립니다[2][6][7].
결론
NestJS와 Express.js는 각각의 장단점을 가지고 있으며, 프로젝트의 요구사항에 따라 선택이 달라질 수 있습니다. 작은 규모의 프로젝트나 빠른 프로토타이핑이 필요할 때는 Express.js가 적합할 수 있으며, 대규모 애플리케이션이나 구조적 일관성이 중요한 프로젝트에서는 NestJS가 더 나은 선택이 될 수 있습니다.
Citations: [1] https://www.geeksforgeeks.org/expressjs-vs-nestjs-5-differences-that-you-should-know/ [2] https://blog.logrocket.com/nestjs-vs-express-js/ [3] https://www.sphinx-solution.com/blog/nestjs-vs-express/ [4] https://www.forestadmin.com/blog/nestjs-vs-expressjs-which-is-better-for-your-project/ [5] https://www.aalpha.net/blog/nestjs-vs-expressjs-difference/ [6] https://nestjs.com [7] https://selleo.com/blog/why-choose-nest-js-as-your-backend-framework [8] https://www.turing.com/blog/what-is-nest-js-why-use-it/ [9] https://www.mitrais.com/news-updates/a-quick-introduction-to-nestjs/ [10] https://blog.nevertoolate.studio/nestjs-essentials-understanding-the-5-core-concepts-897276211f76?gi=1b586c45d0fe [11] https://www.geeksforgeeks.org/unique-features-of-express-js/ [12] https://softprodigy.com/express-js-features-that-make-it-the-best-choice-for-web-application-development/ [13] https://www.scaler.com/topics/expressjs-tutorial/what-is-express-js/ [14] https://intellipaat.com/blog/what-is-express-js/ [15] https://laxaar.com/blog/core-features-of-express-js-1677734143783
NestJS와 Express.js의 보안 기능 차이는
NestJS와 Express.js는 모두 Node.js 기반의 웹 애플리케이션 프레임워크로, 보안 기능에서도 차이점을 보입니다. 아래는 두 프레임워크의 보안 기능 차이를 정리한 내용입니다.
NestJS의 보안 기능
1. 내장 보안 기능
NestJS는 보안 기능을 기본적으로 내장하고 있어, 개발자가 쉽게 보안 조치를 구현할 수 있습니다. 주요 보안 기능은 다음과 같습니다:
- Helmet: HTTP 헤더를 설정하여 보안을 강화합니다[1].
- CORS: 교차 출처 리소스 공유(CORS)를 설정하여 특정 도메인에서만 리소스에 접근할 수 있도록 합니다[1].
- CSRF 보호: CSRF 공격을 방지하기 위한 미들웨어를 제공합니다[3].
- Rate Limiting: 특정 시간 내에 요청 수를 제한하여 서비스 거부(DoS) 공격을 방지합니다[3].
- 인증 및 인가: JWT, OAuth2, Passport 등을 사용하여 인증 및 인가를 쉽게 구현할 수 있습니다[4][11].
2. 모듈화된 보안 접근
NestJS는 모듈화된 아키텍처를 통해 보안 기능을 쉽게 확장하고 관리할 수 있습니다. 예를 들어, 인증 모듈, 인가 모듈 등을 별도로 구성하여 필요에 따라 재사용할 수 있습니다[3][14].
3. 환경 변수 및 설정 관리
NestJS는 환경 변수를 통해 민감한 정보를 안전하게 관리할 수 있는 내장 설정 모듈을 제공합니다[3].
Express.js의 보안 기능
1. 미들웨어를 통한 보안 강화
Express.js는 다양한 서드파티 미들웨어를 사용하여 보안을 강화합니다. 주요 미들웨어는 다음과 같습니다:
- Helmet: HTTP 헤더를 설정하여 보안을 강화합니다[6][7].
- express-rate-limit: 요청 수를 제한하여 DoS 공격을 방지합니다[7].
- csurf: CSRF 공격을 방지하기 위한 미들웨어입니다[7].
2. 사용자 입력 검증 및 위생 처리
Express.js는 사용자 입력을 검증하고 위생 처리하여 SQL 인젝션, XSS 등의 공격을 방지합니다. 이를 위해 다양한 입력 검증 및 위생 처리 라이브러리를 사용할 수 있습니다[7][9].
3. 인증 및 인가
Express.js는 Passport.js와 같은 미들웨어를 사용하여 다양한 인증 및 인가 전략을 구현할 수 있습니다. JWT, OAuth, 세션 기반 인증 등을 지원합니다[16][19].
4. 종속성 관리
Express.js는 npm audit와 같은 도구를 사용하여 종속성의 보안 취약점을 검사하고 업데이트할 수 있습니다[7][10].
결론
NestJS는 보안 기능을 프레임워크에 내장하여 개발자가 쉽게 보안 조치를 구현할 수 있도록 돕는 반면, Express.js는 다양한 서드파티 미들웨어를 통해 보안을 강화합니다. NestJS는 모듈화된 아키텍처와 TypeScript의 강력한 타입 시스템을 통해 보안 기능을 체계적으로 관리할 수 있는 반면, Express.js는 유연성과 확장성을 제공하여 다양한 보안 요구사항에 맞게 커스터마이징할 수 있습니다. 두 프레임워크 모두 강력한 보안 기능을 제공하지만, 프로젝트의 요구사항에 따라 적합한 프레임워크를 선택하는 것이 중요합니다.
Citations: [1] https://docs.nestjs.com/security/helmet [2] https://docs.nestjs.com/openapi/security [3] https://dev.to/drbenzene/best-security-implementation-practices-in-nestjs-a-comprehensive-guide-2p88 [4] https://docs.nestjs.com/security/authentication [5] https://kongbytes.io/blog/nestjs-security/ [6] https://expressjs.com/en/advanced/best-practice-security.html [7] https://dev.to/tristankalos/expressjs-security-best-practices-1ja0 [8] https://expressjs.com/th/advanced/best-practice-security.html [9] https://escape.tech/blog/how-to-secure-express-js-api/ [10] https://www.freecodecamp.org/news/express-js-security-tips/ [11] https://docs.nestjs.com/security/authorization [12] https://dev.to/nadim_ch0wdhury/how-to-create-an-authentication-authorization-feature-in-nest-js-graphql-api-35em [13] https://blog.bitsrc.io/authentication-and-authorization-in-nestjs-39f9d92184ab?gi=ef8b7b8779a3 [14] https://astconsulting.in/blog/2023/08/31/nest-js-authentication-authorization-best-practices/ [15] https://dev.to/nadim_ch0wdhury/how-to-create-an-authentication-authorization-feature-in-express-js-restful-api-ge8 [16] https://www.scaler.com/topics/expressjs-tutorial/authentication_and_authorization_in_express/ [17] https://www.topcoder.com/thrive/articles/authentication-and-authorization-in-express-js-api-using-jwt [18] https://developer.auth0.com/resources/guides/api/express/basic-authorization [19] https://www.geeksforgeeks.org/authentication-strategies-available-in-express/ [20] https://stackoverflow.com/questions/72434150/vulnerability-in-nestjs-8-4-5
NestJS에서 인증과 인가의 구현 방법은
NestJS에서 인증(Authentication)과 인가(Authorization)를 구현하는 방법은 주로 Passport와 JWT(JSON Web Token)를 사용하는 방식으로 이루어집니다. 아래는 이 두 가지를 사용하여 인증과 인가를 구현하는 방법을 단계별로 설명합니다.
인증(Authentication) 구현
1. Auth 모듈 생성
먼저, 인증 관련 모듈, 서비스, 컨트롤러를 생성합니다.
nest generate module auth
nest generate service auth
nest generate controller auth
2. 패키지 설치
Passport와 JWT 관련 패키지를 설치합니다.
npm install --save @nestjs/passport passport passport-local @nestjs/jwt passport-jwt
npm install --save-dev @types/passport-local @types/passport-jwt
3. Auth 모듈 설정
auth.module.ts 파일에서 필요한 모듈을 임포트하고 설정합니다.
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { jwtConstants } from './constants';
@Module({
imports: [
UsersModule,
PassportModule,
JwtModule.register({
secret: jwtConstants.secret,
signOptions: { expiresIn: '60s' },
}),
],
providers: [AuthService, LocalStrategy, JwtStrategy],
controllers: [AuthController],
})
export class AuthModule {}
4. LocalStrategy 구현
local.strategy.ts 파일을 생성하고, LocalStrategy를 구현합니다.
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<any> {
const user = await this.authService.validateUser(username, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
5. JWT Strategy 구현
jwt.strategy.ts 파일을 생성하고, JWT Strategy를 구현합니다.
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { jwtConstants } from './constants';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: jwtConstants.secret,
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
6. AuthService 구현
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<any> {
const user = await this.usersService.findOne(username);
if (user && user.password === pass) {
const { password, ...result } = user;
return result;
}
return null;
}
async login(user: any) {
const payload = { username: user.username, sub: user.userId };
return {
access_token: this.jwtService.sign(payload),
};
}
}
7. AuthController 구현
auth.controller.ts 파일에서 인증 관련 엔드포인트를 정의합니다.
import { Controller, Request, Post, UseGuards, Get } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './local-auth.guard';
import { JwtAuthGuard } from './jwt-auth.guard';
@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;
}
}
인가(Authorization) 구현
1. Role-based Guard 생성
역할 기반 인가를 위해 Guard를 생성합니다.
nest generate guard roles
2. RolesGuard 구현
roles.guard.ts 파일에서 역할 기반 인가를 구현합니다.
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { ROLES_KEY } from './roles.decorator';
import { Role } from './role.enum';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles) {
return true;
}
const { user } = context.switchToHttp().getRequest();
return requiredRoles.some((role) => user.roles?.includes(role));
}
}
3. Roles 데코레이터 생성
roles.decorator.ts 파일에서 역할 데코레이터를 생성합니다.
import { SetMetadata } from '@nestjs/common';
import { Role } from './role.enum';
export const ROLES_KEY = 'roles';
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
4. Role Enum 생성
role.enum.ts 파일에서 역할을 정의합니다.
export enum Role {
User = 'user',
Admin = 'admin',
}
5. Controller에서 RolesGuard 사용
컨트롤러에서 역할 기반 인가를 적용합니다.
import { Controller, Get, UseGuards } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';
import { Role } from './role.enum';
import { JwtAuthGuard } from './jwt-auth.guard';
@Controller('users')
@UseGuards(JwtAuthGuard, RolesGuard)
export class UsersController {
@Get('admin')
@Roles(Role.Admin)
getAdminData() {
return 'This is admin data';
}
@Get('user')
@Roles(Role.User)
getUserData() {
return 'This is user data';
}
}
이와 같이 NestJS에서는 Passport와 JWT를 사용하여 인증과 인가를 쉽게 구현할 수 있습니다. 이러한 구조는 보안성을 높이고, 코드의 유지보수성을 향상시키는 데 도움이 됩니다.
Citations: [1] https://docs.nestjs.com/security/authentication [2] https://adoreje.tistory.com/6 [3] https://www.sipios.com/blog-posts/implementing-authentication-in-nestjs-using-passport-and-jwt [4] https://blog.bitsrc.io/authentication-and-authorization-in-nestjs-39f9d92184ab?gi=ef8b7b8779a3 [5] https://docs.nestjs.com/security/authorization [6] https://velog.io/%40dev_leewoooo/NestJs에서-토큰기반-인증-구현하기-with-JWT [7] https://sjh9708.tistory.com/47 [8] https://dapsu-startup.tistory.com/entry/NestJS-JWT-인증-로그인-기능-구현 [9] https://velog.io/%40jinony/Nest.js를-이용한-OAuth-2.0-구현 [10] https://dev.to/tugascript/nestjs-authentication-with-oauth20-configuration-and-operations-41k [11] https://velog.io/%40from_numpy/NestJS-Authentication-using-Google-OAuth-Session [12] https://dev.to/tugascript/nestjs-authentication-with-oauth20-adding-external-providers-2kj
'개인 개발 공부 일지' 카테고리의 다른 글
| MQTT - 2 (0) | 2024.07.02 |
|---|---|
| MQTT (0) | 2024.07.02 |
| JDBC, 트랜잭션 (0) | 2024.06.24 |
| JSP의 처리 과정, MVC 패턴, 쿠키와 세션 (0) | 2024.06.24 |
| HashMap 동작원리 (0) | 2024.06.24 |