08) 개인 프로젝트) Auth인증 구현 Part 4

Leo·2021년 2월 15일
1

Project-01

목록 보기
8/12
post-thumbnail

username이 아닌 email 사용으로 코드 변경

현재까지는 username이라는 정해진 것으로 auth 인증 절차를 진행했습니다. 이제는 username 대신 email을 이용한 인증 절차로 변경하려고 합니다.

User Entity Email 컬럼 추가

일단 이전에 추가했던 DB의 데이터를 지우기 위하여 user table을 삭제한 후 진행해주세요.

/src/users/user.entity.ts

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ unique: true })
  email: string;

  @Column({ unique: true })
  username: string;

  @Column()
  password: string;
}

이전에 있던 Column들을 많이 삭제 하였습니다. 이제는 사용할 Column을 그때 그때 추가하면서 사용하려고 합니다. 먼저 Auth인증 절차에 사용할 Email를 Column을 만들었습니다.

Email을 이용하여 DB Select를 하기 위한 Service에 메소드 추가

DB에서 Email 값을 이용하여 User정보를 가져오는 메소드를 만듭니다.

/src/users/users.service.ts

...생략
@Injectable()
export class UsersService {
  ...생략
  async getByEmail(email: string) {
    return this.usersRepository.findOne({ email });
  }
}

AuthService username 부분 email로 변경

이전 코드에 있던 username 부분을 email로 바꿔주면 검증 부분에서 UserService의 getByEmail 메소드를 호출하여 검증합니다.

/src/auth/auth.service.ts

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { User } from 'src/users/user.entity';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService,
  ) {}

  async vaildateUser(email: string, password: string): Promise<any> {
    const user = await this.usersService.getByEmail(email);
    if (user && user.password === password) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: User) {
    const payload = { email: user.email, sub: user.id };
    const token = this.jwtService.sign(payload);
    return token;
  }
}

기존 username 역할을 email이 대신 하도록 변경

passport는 특정한 매개 변수 세트(username, password)를 사용하여 validate 메소드를 호출합니다. 하지만 현재 username의 역할을 email이 대신 합니다. 새로운 매개 변수 세트가 email, password가 되었습니다.

앞선 코드와 같이 username부분을 email로 수정해줍니다.

/src/auth/strategies/local.strategy.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-local';
import { User } from 'src/users/user.entity';
import { AuthService } from '../auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super({
      usernameField: 'email',
    });
  }

  async validate(email: string, password: string): Promise<User> {
    const user = await this.authService.vaildateUser(email, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

새 user 추가 경로를 오픈하기

새 user를 추가하기 위하여 기존에 막혀있던 createNewUser의 경로를 오픈해줍니다.

/src/users/users.controller.ts

...생략

@Controller('users')
export class UsersController {
  
  ...생략

  @Public()
  @Post()
  async createNewUser(@Body() user: User): Promise<void> {
    await this.usersService.createNewUser(user);
  }
}

Test Request && Response

user 추가

POST http://localhost:3000/users

Request

[
    {
        "email": "test1@gmail.com",
        "username": "test1",
        "password": "qwer1234@"
    },
    {
        "email": "test2@gmail.com",
        "username": "test2",
        "password": "qwer3333"
    }
]

Auth 인증 로그인

POST http://localhost:3000/auth/login

Request

{
    "email": "test1@gmail.com",
    "password": "qwer1234@"
}

추가한 첫번째 값 가져오기

GET http://localhost:3000/users/1

Response

{
    "id": 1,
    "email": "test1@gmail.com",
    "username": "test1",
    "password": "qwer1234@"
}

GET http://localhost:3000/users/2

Response

{
    "id": 2,
    "email": "test2@gmail.com",
    "username": "test2",
    "password": "qwer3333"
}

Auth인증을 하지 않았거나 토큰이 만료되었을 경우

GET http://localhost:3000/users/1

Response

{
    "statusCode": 401,
    "message": "Unauthorized"
}

다음 포스트에서 수정될 사항

  • secret key의 저장 장소
  • token의 시간 설정
  • username이 아닌 email 사용
  • password 암호화

Github 레포 주소

profile
개발자

1개의 댓글

comment-user-thumbnail
2021년 11월 29일

정리가 정말 잘되어있네요. 잘보고갑니다~

답글 달기