jwt, passport를 활용하여 nest.js에서 인증과 인가에 대해서 구현해 보고자 한다.
nest.js를 배운지 얼마 안된 만큼 nest.js에서 제공하는 sample을 활용하여 nest.js가 추구하는 방향으로 개발을 하고자 한다.
일단 mysql을 DB로 사용 할 것이기 때문에 typeORM 세팅을 해주자.
공식 문서에 나와 있는데로 필요한 module를 받고 app.module에 세팅을 해주자!
$ npm install --save @nestjs/typeorm typeorm mysql2
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [],
synchronize: true,
}),
],
})
export class AppModule {}
// port, host, username, password 등등은 git에 올라 가지 않게 따로 파일을 빼서 관리 하는것이 좋다.
$ npm run start:dev
실행 결과 정상 작동 한다. 이제 DB와 nest.js 간에 연결을 위해 entity를 생성해 보자.
// user.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn("uuid") // 고유 아이디
id: number;
@Column()
email: string;
@Column()
password: string;
}
간단하게 email과 password를 통해 회원가입을 한다.
entity를 생성했으니 controller, service를 생성하여 module에 연결 하여 보자
// user.controller.ts
import { Controller } from "@nestjs/common";
@Controller()
export class UserController {
}
// user.service.ts
import { Injectable } from "@nestjs/common";
@Injectable()
export class UserService {
}
// user.module.ts
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { UserController } from "./user.controller";
import { User } from "./user.entity";
import { UserService } from "./user.service";
@Module({
imports: [
TypeOrmModule.forFeature([User]),
],
providers: [
UserService
],
controllers: [
UserController,
]
})
export class UserModule {}
공식 github sample를 보면 Dto라는 새로운 타입을 쓴다. DTO라는 것은 나중에 정리 하는것으로 하고 일단 진행해 보자
import { Body, Controller, Post } from "@nestjs/common";
import { CreateUserDto } from "./dto/create-user.dto";
import { User } from "./user.entity";
import { UserService } from "./user.service";
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService){}
@Post()
create(@Body() createUserDto: CreateUserDto): Promise<User> {
console.log(createUserDto);
return this.userService.create(createUserDto)
}
}
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { CreateUserDto } from "./dto/create-user.dto";
import { User } from "./user.entity";
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>
){}
async create(createUserDto: CreateUserDto):Promise<User> {
const {email, password} = createUserDto;
const result = await this.userRepository.save({
email,
password
});
return result
}
}
간단하게 emil과 password를 받아서 회원 정보를 저장해 준다. 그러면 postman으로 테스트 해보자.
에러가 나온다...
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserModule } from './users/user.module';
@Module({
imports: [
UserModule,
TypeOrmModule.forRoot({
type: 'mysql',
host: '127.0.0.1',
port: 3306,
username: 'root',
password: '123123123',
database: 'auth_jwt',
entities: [], // entity 정보를 추가해 주지 않아 User Entity를 찾지 못한다.
synchronize: true,
}),
],
})
export class AppModule {}
공식문서를 보면 entity의 경로를 하나하나 추가해 줘야 하지만 github을 보니 autoLoadEntities: true를 설정해 주면 알아서 entitty를 등록해 준다.
추가하고 다시 포스트맨을 날려보자.
정상적으로 날라간다.
정상적으로 회원가입 되는거 같지만 현재 빠진기능이 많다...
받아오는 데이터 형식이 틀렸을 경우의 예외처리, 비밀번호 암호화 해서 저장하기, 이미 있는 이메일인지 확인하기 등등등...
다음 글에서 이 예외처리들을 처리해 보자