혼자 고민해보기_ 개발/TIL (Today I Learned)

20230804(금)_ nest js 공부

nuri-story 2023. 8. 6. 10:04

금일 달성 항목

1) 따라하면서 배우는 nest js 80% 수강


문제 해결 과정 1 - Property 'findOne' does not exist on type 'AuthRepository'. ts(2339)

[문제]

findOne을 repository에서 찾을 수 없다고 해서 해매고 있었습니다.

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthRepository } from './auth.repository';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './auth.entity';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(
    @InjectRepository(AuthRepository)
    private authRepository: AuthRepository,
  ) {
    super({
      secretOrKey: 'Secret1234',
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
    });
  }
  async validate(payload) {
    const { username } = payload;
    const user: User = await this.authRepository.findOne(username);

    if (!user) {
      throw new UnauthorizedException();
    }

    return user;
  }
}
    const user: User = await this.authRepository.findOne(username);

 

 

 

[시도]

챗 GPT에게 질문하였으나 해결하진 못했습니다.

 

https://github.com/typeorm/typeorm/issues/2118

 

Property 'findOne' does not exist on type · Issue #2118 · typeorm/typeorm

Issue type: [x] question [x] bug report [ ] feature request [ ] documentation issue Database system/driver: [ ] cordova [ ] mongodb [ ] mssql [ ] mysql / mariadb [ ] oracle [x] postgres [ ] sqlite ...

github.com

위와 같은 내용이 있어

    const user= await this.authRepository(User).findOne(username);

해봤지만 여전히 실패

 

[해결]

동료분에게 여쭤봐서 해결했습니다!

 

jwt.strategy.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthRepository } from './auth.repository';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './auth.entity';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private authRepository: AuthRepository) {
    super({
      secretOrKey: 'Secret1234',
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
    });
  }
  async validate(payload) {
    const { username } = payload;
    const user: User = await this.authRepository.findByUserName(username);

    if (!user) {
      throw new UnauthorizedException();
    }

    return user;
  }
}

 

auth.repository.ts

import { Repository } from 'typeorm';
import { User } from './auth.entity';
import {
  ConflictException,
  Injectable,
  InternalServerErrorException,
  UnauthorizedException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { AuthCredentialsDto } from './dto/auth-credential.dto';
import * as bcrypt from 'bcryptjs';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthRepository {
  constructor(
    @InjectRepository(User) private authRepository: Repository<User>,
    private jwtService: JwtService,
  ) {}

  async findByUserName(username: string): Promise<User> {
    return await this.authRepository.findOne({ where: { username } });
  }

  async createUser(authCredentialsDto: AuthCredentialsDto): Promise<void> {
    const { username, password } = authCredentialsDto;

    const salt = await bcrypt.genSalt();
    const hashedPassword = await bcrypt.hash(password, salt); // 비밀번호 암호화

    const user = this.authRepository.create({
      username,
      password: hashedPassword,
    });

    try {
      await this.authRepository.save(user);
    } catch (error) {
      if (error.code === '23505') {
        throw new ConflictException('Existing username');
      } else {
        throw new InternalServerErrorException(); //서버 내부 오류를 나타내며, 클라이언트에게는 일반적인 오류 메시지를 제공
      }
    }
  }

  async signIn(
    authCredentialsDto: AuthCredentialsDto,
  ): Promise<{ accessToken: string }> {
    const { username, password } = authCredentialsDto;
    const user = await this.authRepository.findOne({ where: { username } });

    // 유저와 입력한 내가 입력한 비밀번호 값, 데이터가 가진 유저의 비밀번호랑 비교(compare)하기
    if (user && (await bcrypt.compare(password, user.password))) {
      // 유저 로그인 성공 전 토큰 생성
      const payload = { username };
      const accessToken = await this.jwtService.sign(payload);

      return { accessToken };
    } else {
      throw new UnauthorizedException('login fail '); // 아니면 풰일~ 반환
    }
  }
}

 

[알게된 점]

아직 구조를 명확히 이해를 못해서 자잘한 오류해결도 못하는 것 같습니다.

공부가 더 필요합니다.