여기까지 import 된 부분에 대한 설명이었고, auth.module의 imports를 보면 UsersModule, PassportModule을 가져왔고 JwtModule은 register를 통해 등록하였어요. register() 안쪽 부분이 JwtModule에 대한 Options이에요.
auth module까지 끝났고요. 이제 guards에 대한 부분을 구현해 보도록 하겠습니다.
Guards의 역할은 request가 처리될지 말지를 결정합니다. 예를 들어 로그인에 정상적으로 성공한 경우 이후의 프로세스를 실행할 수 있지만, 로그인에 실패한 경우 더 이상 접근할 수 없도록 하는 것이지요.
'app.controllers.ts'를 열어 수정해줍니다. app.으로 왔다니 뭔가 끝이 보이는 거 같네요.
import {
ExecutionContext,
Injectable,
UnauthorizedException,
} from'@nestjs/common';
import { AuthGuard } from'@nestjs/passport';
@Injectable()
exportclassJwtAuthGuardextendsAuthGuard('jwt') {
canActivate(context: ExecutionContext) {
// Add your custom authentication logic here// for example, call super.logIn(request) to establish a session.returnsuper.canActivate(context);
}
handleRequest(err, user, info) {
// You can throw an exception based on either "info" or "err" argumentsif (err || !user) {
throw err || new UnauthorizedException();
}
return user;
}
}
nest cli는 많은 기능을 제공하는 데, 그중 generator를 이용하여 CRUD를 구현해 보겠습니다.
먼저 nest -h 명령어를 통해 nest에서 사용하는 alias를 확인해 볼게요.
nest -h
Usage: nest <command> [options]
Options:
-v, --version Output the current version.
-h, --help Output usage information.
Commands:
new|n [options] [name] Generate Nest application.
build [options] [app] Build Nest application.
start [options] [app] Run Nest application.
info|i Display Nest project details.
update|u [options] Update Nest dependencies.
add [options] <library> Adds support for an external library to your project.
generate|g [options] <schematic> [name] [path] Generate a Nest element.
Schematics available on @nestjs/schematics collection:
┌───────────────┬─────────────┬──────────────────────────────────────────────┐
│ name │ alias │ description │
│ application │ application │ Generate a new application workspace │
│ class │ cl │ Generate a new class │
│ configuration │ config │ Generate a CLI configuration file │
│ controller │ co │ Generate a controller declaration │
│ decorator │ d │ Generate a custom decorator │
│ filter │ f │ Generate a filter declaration │
│ gateway │ ga │ Generate a gateway declaration │
│ guard │ gu │ Generate a guard declaration │
│ interceptor │ in │ Generate an interceptor declaration │
│ interface │ interface │ Generate an interface │
│ middleware │ mi │ Generate a middleware declaration │
│ module │ mo │ Generate a module declaration │
│ pipe │ pi │ Generate a pipe declaration │
│ provider │ pr │ Generate a provider declaration │
│ resolver │ r │ Generate a GraphQL resolver declaration │
│ service │ s │ Generate a service declaration │
│ library │ lib │ Generate a new library within a monorepo │
│ sub-app │ app │ Generate a new application within a monorepo │
│ resource │ res │ Generate a new CRUD resource │
└───────────────┴─────────────┴──────────────────────────────────────────────┘
맨 아래에 보시면 CRUD가 있습니다. resource 또는 res를 이용하면 CRUD에 필요한 템플릿을 만들 수 있습니다.
저는 auth라는 CRUD 기능을 만들어 보겠습니다.
nest g res auth
? What transport layer do you use?
> REST API
GraphQL (code first)
GraphQL (schema first)
Microservice (non-HTTP)
WebSockets
? Would you like to generate CRUD entry points? (Y/n) Y
CREATE src/auth/auth.controller.spec.ts (556 bytes)
CREATE src/auth/auth.controller.ts (883 bytes)
CREATE src/auth/auth.module.ts (240 bytes)
CREATE src/auth/auth.service.spec.ts (446 bytes)
CREATE src/auth/auth.service.ts (607 bytes)
CREATE src/auth/dto/create-auth.dto.ts (30 bytes)
CREATE src/auth/dto/update-auth.dto.ts (164 bytes)
CREATE src/auth/entities/auth.entity.ts (21 bytes)
UPDATE src/app.module.ts (388 bytes)
nest g res 명령 실행 시 어떤 전송방법을 사용할지, CRUD point를 생성할지에 대해 물어봅니다.
저는 REST API, Y를 선택하여 생성하였습니다. 이제 start를 해보겠습니다.
yarn start
"Nest application successfully started" 성공적으로 시작했다고 합니다.
"http://localhost:3000/auth"로 접속해 보니 "Hello" 메시지를 정상적으로 만나볼 수 있습니다.
하지만 우리는 이걸 목적으로 한 것이 아니기에 "http://localhost:3000/auth/1"로 접속해 봅니다.
이렇게 나오게 되면, Resource생성이 정상적으로 완료되었음을 확인할 수 있습니다.
생성된 폴더 구조를 살펴보도록 하겠습니다.
.ts파일 중 spec.ts는 테스트 파일, dto, entities폴더에 있는 파일은 DB와 관련된 파일입니다.
먼저 이외의 controller, moduel, service에 대해서 살펴보겠습니다.
> service
service파일은 비즈니스 로직을 처리하는 파일입니다. auth.service.ts의 AuthService를 살펴보면
create, findAll, findOne, update, remove라는 메서드가 있습니다.
방금 전, "http://localhost:3000/auth/1"를 호출하였을 때 만났던 메시지가 findOne 메서드를 통해 response 되었겠네요.
findOne(id: number) {
return`This action returns a #${id} auth`;
}
app.controller.ts를 보면 Spring 프레임워크와 굉장히 익숙한 구조임을 알 수 있어요. 서버가 수행해야 할 일을 '@' Annotation, Decorator(어노테이션, 데코레이터)로 기술합니다.
@Controller 데코레이터를 클래스에 선언함으로써 해당 클래스는 컨트롤러의 역할을,
@Get() 데코레이터를 가진 getHello 함수는 root경로로 들어오는 request(요청)를 처리할 수 있습니다.
@Controller() 데코레이터를 보면 ( )가 있다. 여기에 인자를 입력하여 라우팅 경로는 정해줄 수 있어요. 예를들어 backend에서 주로 사용하는 'app'이라고 입력하면 우리가 지난번에 테스트했던 https://localhost:3000/app으로 접근해야 "hello world"를 만날 수 있는 것이죠!
@Get() 안에는 '/'가 생략되어 루트 경로이며, '/helloworld'로 변경한다면, 기존의 http://localhost:3000/ 요청에 대하여 404 에러를 만나게 될 것이고, http://localhost:3000/helloworld로 요청해야 "hello world"페이지를 응답받을 수 있을 것이다.
중간에 어떤 package manager를 사용할 것인지 물어본다. 필자는 yarn을 선택하였다.
? Which package manager would you ❤️ to use? yarn
✔ Installation in progress... ☕
🚀 Successfully created project bcheck-auth-nest
👉 Get started with the following commands:
$ cd [project name]
$ yarn run start
Thanks for installing Nest 🙏
Please consider donating to our open collective
to help us maintain this package.
🍷 Donate: https://opencollective.com/nest
위와 같이 뜨면 프로젝트 생성이 완료된 것이다. 생성된 프로젝트를 개발 툴로 열어 구조를 살펴보자.
참고로 글쓴이는 IntelliJ를 이용한다.
[Project Name] - [src] 아래에 app.으로 시작하는 파일들과 main.ts 파일이 생성되었음을 확인할 수 있다.
각각의 역할은 아래와 같다.
app.controller.spec.ts
컨트롤러 단위 테스트용
app.controller.ts
기본 컨트롤러
app.module.ts
application의 root module
app.service.ts
단일 메서드를 사용하는 기본 서비스
main.ts
NestFactory를 사용하여 Nest application 인스턴스를 작성하는 엔트리 파일
3. main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
Nest application은 인스턴스를 생성하기 위해 NestFactory를 사용한다. NestFactory는 application 응용프로그램 인스턴스를 만들 수 있는 정적 메서드를 제공하며, careate() 메서드는 INestApplication (인터페이스 응용프로그램 객체)을 반환한다.
Spring 개발 유경험자로 Node를 처음 접하며 Study하는 내용을 기록해보고자 한다.
1. NestJS는?
NestJS는 Node.js 기반의 웹 API 프레임워크이다. 들어만 본 Express를 사용하고, Node.js의 자체 특성인 사용하기 쉽고, 확장성이 뛰어나다. 이로 인해 품질이 일정치 않고, 적합한 라이브러리를 찾기 위해 사용자의 수고가 필요하다는 단점이 있는데 이를 보완하는 것이 NestJS이다.
Angular의 영향을 많이 받은 NestJS는 DI(Dependency Injection, 의존성 주입)이라는 객체지향 개념을 도입한 부분에서 Spring과 공통점이 있다. 소스를 보아도 스프링에서 Anotation이라고 불리는 '@'가 보인다.