7/18 JWT(4)

JK·2023년 7월 18일
0

오늘로 JWT를 끝낸다는 생각으로 구현을 해봤습니다!!

src/app.module.ts

import { ChatGptAiModule } from './chat-gpt-ai/chat-gpt-ai.module';

import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { AuthModule } from './auth/auth.module';
import * as mongoose from 'mongoose';

@Module({
@@ -18,7 +19,8 @@ import * as mongoose from 'mongoose';
    UserModule,
    S3Module,
    VideoModule,
    ChatGptAiModule,
    AuthModule],
  controllers: [AppController],
  providers: [AppService],
})

src/auth/auth.module.ts

import { Module, forwardRef } from '@nestjs/common';
import { AuthService } from './auth.service';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { JwtStrategy } from './jwt/jwt.strategy';
import { UserRepository } from 'src/user/user.repository';
import { UserModule } from 'src/user/user.module';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt', session: false }),

    JwtModule.register({
      secret: 'secret',
      signOptions: { expiresIn: '1y' },
    }),

    forwardRef(() => UserModule),
  ],
  providers: [AuthService, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}

src/auth/auth.service.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UserRepository } from 'src/user/user.repository';
import { LoginRequestDto } from './dto/login.request.dto';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private readonly userRepository: UserRepository,
    private jwtService: JwtService,
  ) {}

  async jwtLogIn(data: LoginRequestDto) {
    const { id, password } = data;

    //* 해당하는 email이 있는지
    const user = await this.userRepository.findUserById(id);

    if (!user) {
      throw new UnauthorizedException('아이디와 비밀번호를 확인해주세요.');
    }

    //* password가 일치한지
    const isPasswordValidated: boolean = await bcrypt.compare(
      password,
      user.password,
    );

    if (!isPasswordValidated) {
      throw new UnauthorizedException('아이디와 비밀번호를 확인해주세요.');
    }

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

    return {
      token: this.jwtService.sign(payload),
    };
  }
}

src/auth/dto/login.request.dto.ts

import { PickType } from '@nestjs/swagger';
import { User } from 'src/user/user.schema';

export class LoginRequestDto extends PickType(User, [
  'id',
  'password',
] as const) {}

src/auth/jwt/jwt.guard.ts

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

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

src/auth/jwt/jwt.strategy.ts

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

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

  //async validate(payload) {}
}

src/user/user.controller.ts

import { UserRequestDto } from './dto/user.request.dto';
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';

@Controller('user')
@UseInterceptors(SuccessInterceptor)
@UseFilters(HttpExceptionFilter)
export class UserController {
  constructor(
    private readonly userService: UserService,
    private readonly authService: AuthService,
  ) {}

  @ApiOperation({ summary: '현재 유저 가져오기' })
  @Get()
@@ -36,8 +41,8 @@ export class UserController {

  @ApiOperation({ summary: '로그인' })
  @Post('login')
  logIn(@Body() data: LoginRequestDto) {
    return this.authService.jwtLogIn(data);
  }

  @ApiOperation({ summary: '로그아웃' })

src/user/user.module.ts


import { Module, forwardRef } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './user.schema';
import { UserRepository } from './user.repository';
import { AuthModule } from 'src/auth/auth.module';

@Module({
  imports: [
    MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
    forwardRef(() => AuthModule),
  ],
  controllers: [UserController],
  providers: [UserService, UserRepository],
  exports: [UserService, UserRepository],
})
export class UserModule {}

src/user/user.repository.ts

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

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

  async existsById(id: string): Promise<boolean> {
    const result = await this.userModel.exists({ id });
    if (result) return true;

이렇게 구현을 해서

토큰 생성까지 성공했습니다!!!
이제 인증 부분만 구현하면 끝입니다!
이걸 하루 만에 해내는 다른 분들이 대단하다고 생각하고 더 열심히 공부해야 될 거 같습니다 :)

profile
^^

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

정말 유익한 글이었습니다.

답글 달기

관련 채용 정보