본문 바로가기
개인과제,팀과제

Trello Service/로그인

by 콩국수는설탕 2024. 7. 22.

로그인시 사용할 DTO 정의해주기

import { PickType } from "@nestjs/swagger";
import { User } from "src/user/entities/user.entity";

export class SignInDto extends PickType(User, ['email', 'password']){}

 회원가입 에서 설명한 dto 와 다를게 없어 설명은 생략합니다.

Strategy 구현하기

import { Injectable, UnauthorizedException } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy } from "passport-jwt";
import { AuthService } from "../auth.service";

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy){
    constructor(private readonly authService: AuthService){
        super({
           usernameField: 'email',
           passwordField: 'password',
        });
    }
    async validate(email: string, password: string){
        const user = await this.authService.validateUser({email, password})

        if(!user){
            throw new UnauthorizedException('일치하는 인증정보가 없습니다.')
        }

        return user
    }
}

기본적으로 PassportStrategy 를 통해 Strategy를 만들면
디폴트 로 이 strategy 의 이름은 'local'  이 되는걸알고 진행하면된다

먼저 nest 에서 제공하는 passport 를 통해 Middleware와 비슷한 역활을 해주는
JwtStrategy 를 생성한 모습이다

이 LocalStrategy 는 기본적으로 유저아이디와 패스워드를 받아오는 필드명이
username 과 password 으로 받아오기 때문에 현재상황과 맞는
'email' 과 'password' 로 수정해준 모습이다

그다음 validateUser 를 사용해 유저정보를 검증하는 validate 메소드를 생성해주었다

validateUser 의 모습

validateUser 를 보면
email을 토대로 userRepository에서 정보를 하나 찾은다음
변수 user에 id password email 을 담아주는 모습을 볼수있다

그 아래 verifyPassword 를 추가로 정의를 해주었는데

이렇게 input 으로 온 비밀번호와 실제 저장된 비밀번호를 비교해주는 메소드를 정의해준모습이다

다시 validateUser 로 돌아가서 실제 입력받은 password 와 저장된 user의 password 를 비교하고
만약 이 검증단계들을 통과한다면 id 와 email 을 return 하게 만들었다

다시 strategy 로 돌아가면
변수 user 에는 검증된 정보가 들어가게되고
이걸 return 하도록 만들었습니다.

 

생성한 Strategy 로 Guard 만들어주기

import { Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";

@Injectable()
export class LocalAuthGuard extends AuthGuard('local'){}

아까 말했다싶이 Strategy 를 passport - local 로 가져오면 디폴트로 이름은 local이 된다고했다

제발제발제발기억하자제발

필자는 이거땜에 이새벽에 한시간반동안 오류를 경험했다, 부디 나와같은 멍청이슈가 생기지않길..

무튼 본론으로 돌아가서, extends 를 통해 생성한 local을 불러와서 LocalAuthGuard 를 만들어주었다

실제 적용하게되면,

이렇게 컨트롤러에 추가해주면된다 // 새삼 node도 얼마공부한건 아니지만 nest...정말 편하다

Controller 에 로그인 로직 구현하기

정말 간단하다,
단지 회원가입 과 틀린거라곤 @Request() req, 를 통해 실제 req를 보내는 유저의 정보를
가져올수 있게하여 signIn 의 파라미터로 유저의 아이디와 이메일을 넘겨준 모습이다.ㅁ

그리고 리턴은 회원가입과 동일한 형식으로 정의를 해주었고
추가로 메세지 부분은 따로 constants 디렉토리를 생성한후 관리를 할 예정이다.

 

대망의 Service 에서 로그인 로직 구현하기(여기가 핵심이긴함 ㅋㅋ)

야심한 새벽이니 말투도 야심하게 함 깔깔. 왜 ? 어짜피 이 tistory는 나중에 찾아볼 나를위한거니깐 낄낄

왜 이리 간단하지? 라는 생각이 들수도 있지만 이럴땐 팀장님의 말을 기억해보도록하자
손XX : 민수님 코딩을 잘해보일려면 약간의 겉멋이 필요합니다 
아... 그는 정말 신이야...

팀장님이 말하는 겉멋중 하나 : 코드의 가독성을 높여야하기 때문에 긴 로직들은 따로 관리하는것도 좋은방법이다.

그렇다면 generateTokens 를 살펴보자

이렇게 따로 관리하면 refresh Token 까지 깔끔히 관리 할수있어 정말 가독성이 좋다고 생각한다.(아닌가..?)

이제 서버를 실행하면 ?

응 오류야 한잔해~ 

은 농담이고 이렇게 오류가 뜰땐 당황하지 말고 터미널을 읽어보자,
막상 읽어보면? 참 간단한 오류이다 바로 JwtService 에 대한 DI 를 해주지 않은것이다.

auth.module.ts 에 JwtService 를 위한 DI 를 해주도록 하자



이렇게 해주고 서버만 실행하면 오류는 간단히 해결된다.

인섬니아 테스트 결과

 

'개인과제,팀과제' 카테고리의 다른 글

Trello Service 클론코딩/회원가입  (2) 2024.07.22