7/19 JWT 인증

JK·2023년 7월 20일
0

어제 로그인하고 토큰을 생성하는 부분까지 완료했습니다
오늘은 토큰을 사용해 인증을 하는 부분을 구현해봤습니다

src/auth/auth.service.ts

    const payload = { id: id, sub: user.id };
    const payload = { id: id, sub: user._id };

어제 위에 있는 코드처럼 토큰의 payload 부분에 들어갈 정보에 id 값과 mongo db에서 자동으로 생성되는 id 값을 넣어주려 했는데 오늘 다시 보니 똑같은 사용자의 아이디만 2번 들어간 걸 확인해서 아래 코드로 바꿔주었습니다

src/auth/jwt/jwt.payload.ts

export type payload = {
  id: string;
  sub: string;
};

src/auth/jwt/jwt.strategy.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { UserRepository } from 'src/user/user.repository';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly userRepository: UserRepository) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'secret',
      ignoreExpiration: false,
    });
  }

  async validate(payload) {
    const user = await this.userRepository.findUserByIdWithoutPassword(
      payload.sub,
    );

    if (user) {
      return user;
    } else {
      throw new UnauthorizedException('접근 오류');
    }
  }
}

src/common/decorators/user.decorator.ts

import { ExecutionContext, createParamDecorator } from '@nestjs/common';

export const CurrentUser = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);

src/user/user.controller.ts

import {
  Body,
  UseFilters,
  UseGuards,
  UseInterceptors,
  Req,
} from '@nestjs/common';
import { Controller, Get, Post } from '@nestjs/common';
import { UserService } from './user.service';
import { SuccessInterceptor } from 'src/common/interceptors/success.interceptor';
@@ -8,6 +14,9 @@ import { ApiOperation, ApiResponse } from '@nestjs/swagger';
import { ReadOnlyUserDto } from './dto/user.dto';
import { AuthService } from 'src/auth/auth.service';
import { LoginRequestDto } from 'src/auth/dto/login.request.dto';
import { JwtAuthGuard } from 'src/auth/jwt/jwt.guard';
import { CurrentUser } from 'src/common/decorators/user.decorator';
import { User } from './user.schema';

@Controller('user')
@UseInterceptors(SuccessInterceptor)
@@ -19,9 +28,10 @@ export class UserController {
  ) {}

  @ApiOperation({ summary: '현재 유저 가져오기' })
  @UseGuards(JwtAuthGuard)
  @Get()
  getCurrentUser(@CurrentUser() user: User) {
    return user.readOnlyData;
  }

src/user/user.repository.ts

    @InjectModel(User.name) private readonly userModel: Model<User>,
  ) {}

  async findUserByIdWithoutPassword(userId: string): Promise<User | null> {
    const user = await this.userModel.findById(userId).select('-password');
    return user;
  }

  async findUserById(id: string): Promise<User | null> {
    const users = await this.userModel.findOne({ id });
    return users;

여기까지 구현을 해서 JWT 인증을 성공했습니다

postman을 사용하여 확인했습니다

회원가입

회원가입 결과

로그인

로그인 결과

토큰 인증

토큰 인증 결과

profile
^^

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

많은 도움이 되었습니다, 감사합니다.

답글 달기

관련 채용 정보