일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- react
- kafka
- 반복문
- vue
- 조건문
- 개발이 취미인 사람
- props
- SWIFT
- 상속
- It
- java
- Sequelize
- Nest.js
- swagger
- back-end
- file upload
- jpa
- 개발자
- restful api
- state
- class
- Kotlin
- Producer
- node.js
- javascript
- front-end
- 코틀린
- AWS
- spring boot
- component
- Today
- Total
개발이 취미인 사람
[Nest.js] Nest.js API 만들기 (8) - Authentication(Passport, Passport-Local) & Guards 로그인 본문
[Nest.js] Nest.js API 만들기 (8) - Authentication(Passport, Passport-Local) & Guards 로그인
RyanSin 2021. 11. 19. 02:14- 개요
안녕하세요. 이번 시간에는 Nest.js에서 로그인 기능을 구현해보는 시간을 가져보겠습니다.
Nest.js 공식 홈페이지에서는 Passport를 권장하고 있습니다.
공식 홈페이지: https://docs.nestjs.com/security/authentication
인증 방식으로 passport-local 방식과 passport-jwt 방식을 소개하고 있습니다. 이번 시간에는 passport-local 방식을 사용해서 로그인 인증을 진행하겠습니다.
- 설정
우리는 몇 가지 모듈을 설치해야 합니다. 아래 모듈을 설치 해주세요.
#npm
npm install --save @nestjs/passport passport passport-local
npm install --save-dev @types/passport-local
#yarn
yarn add @nestjs/passport passport passport-local
yarn add @types/passport-local --dev
모듈을 설치했다면 auth module과 auth service를 만들어줍니다.
#module 생성
nest g module auth --no-spec
#service 생성
nest g service auth --no-spec
다음으로는 auth 폴더 안에 guards 폴더와 strategies 폴더를 생성합니다.
- local-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
- auth.local.strategy.ts
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) {
// usernaem 키 이름 변경 user_id로 요청
super({
usernameField: 'user_id',
});
}
async validate(user_id: string, password: string): Promise<any> {
console.log('LocalStrategy');
const user = await this.authService.validateUser(user_id, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
auth.local.strategy.ts 파일에서 중요한 부분은 super();를 통해 부모(PassportStrategy) 속성을 변경해 HTTP 요청 시 username 키 값이 아닌 user_id 키 값으로 요청이 가능하게 변경을 해줘야 합니다.
그리고 validate라는 이름을 꼭 사용해야 합니다. 만약 이름을 변경하고 사용하면 아래와 같은 에러가 발생합니다.
validate 메서드명을 사용하지 않고 다른 메소드 이름을 사용했기 때문에 찾을 수 없다는 Error입니다.
- auth.module.ts
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './strategies/auth.local.strategy';
import { AuthService } from './auth.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserRepository } from 'src/repository/user.repository';
@Module({
imports: [TypeOrmModule.forFeature([UserRepository]), PassportModule],
providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
우리가 생성한 LocalStrategy와 PassportModule을 등록해줍니다. 그리고 UserPepository를 등록합니다.
- auth.service.ts
import { Injectable } from '@nestjs/common';
import { UserRepository } from 'src/repository/user.repository';
@Injectable()
export class AuthService {
constructor(private userRepository: UserRepository) {}
/**
* @author Ryan
* @description 단일 유저 조회
*
* @param user_id 유저 아이디
* @param password 유저 비밀번호
* @returns User
*/
async validateUser(user_id: string, password: string): Promise<any> {
console.log('AuthService');
const user = await this.userRepository.findByLogin(user_id, password);
//사용자가 요청한 비밀번호와 DB에서 조회한 비밀번호 일치여부 검사
if (user && user.password === password) {
const { password, ...result } = user;
//비밀번호를 제외하고 유저 정보를 반환
return result;
}
return null;
}
}
아까 생성한 auth.serivce.ts 파일에는 실제 DB에 접근해서 유저를 조회하고 로그인 비즈니스 로직을 구현합니다.(현재 비밀번호 암호화는 따로 하지 않았습니다. 다음 시간에 진행하겠습니다.)
- user.repository.ts
//로그인 유저 조회
async findByLogin(user_id: string, password: string): Promise<User> {
const user = await this.findOne({ where: { user_id, password } });
if (!user) {
throw new ForbiddenException('아이디와 비밀번호를 다시 확인해주세요.');
}
return user;
}
user.repository 안에서 해당 메서드를 추가해 클라이언트에게 받은 아이디와 비밀번호를 통해 유저를 찾습니다.
- user.controller.ts
@UseGuards(LocalAuthGuard)
@Post('/auth/login')
async login(@Request() req) {
console.log('Login Route');
return req.user;
}
Nest.js에서는 Guards라는 기능을 제공합니다. 인증을 기능을 구현할 때 사용합니다.
간단하게 공식 홈페이지 내용을 확인해보면 Guardsms 해당 @Post Route Handler가 실행되기 전에 실행된다고 나와있습니다.
실제 요청을 진행하는 계층을 확인하면 아래 순서로 진행됩니다.
1. LocalStrategy -> 2. AuthService -> 3. Login Route -> 4. Client
- 요청 및 응답
이번 시간에는 Passport LocalStrategy 방식에 대해 알아봤습니다. 꼭 실습을 통해 확인해보시는 걸 추천드리겠습니다.
소스 저장소
github: https://github.com/Ryan-Sin/Node_Nest/tree/v7
'백앤드(Back-End) > Nest.js' 카테고리의 다른 글
[Nest.js] Nest.js API 만들기 (10) - 예외처리(Exception Filters) (0) | 2021.11.27 |
---|---|
[Nest.js] Nest.js API 만들기 (9) - Authentication(Passport-Jwt) & Guards 로그인 인증 (0) | 2021.11.20 |
[Nest.js] Nest.js API 만들기 (6) - TypeORM API서버 적용(CRUD) (1) | 2021.11.13 |
[Nest.js] Nest.js API 만들기 (5) - TypeORM 개념 및 설치 (0) | 2021.11.13 |
[Nest.js] Nest.js API 만들기 (4) - 미들웨어(Middleware) (0) | 2021.11.11 |