[2024.07.30 TIL] 내일배움캠프 74일차 (최종 팀프로젝트, 카카오 소셜 로그인 API 구현)

My_Code·2024년 7월 30일
0

TIL

목록 보기
89/113
post-thumbnail

본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.


💻 TIL(Today I Learned)

📌 Today I Done

✏️ 카카오 소셜 로그인 API 구현

  • 그럼 아래와 같은 화면에서 카카오 로그인이 가능

  • 즉, 기본적인 인증 과정을 우리가 하는 게 아니라 카카오에서 진행해주기 때문에 우리는 그냥 인증된 결과에 대한 값만 처리하면 됨

  • 아래는 PassportStrategy를 상속받아서 사용한 카카오 Strategy

import { ConflictException, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { InjectRepository } from '@nestjs/typeorm';
import { Strategy } from 'passport-kakao';
import { User } from 'src/entities/users/user.entity';
import { Repository } from 'typeorm';

// KAKAO_CALLBACK_URL를 통해서 웹브라우저에서 로그인 진행
// 반환되는 토큰 값을 가지고 다른 기능들 사용

@Injectable()
export class KakaoStrategy extends PassportStrategy(Strategy, 'kakao') {
  constructor(
    private readonly configService: ConfigService,
    @InjectRepository(User) private readonly usersRepository: Repository<User>
  ) {
    super({
      clientID: configService.get('KAKAO_CLIENT_ID'),
      clientSecret: configService.get('KAKAO_CLIENT_SECRET'),
      callbackURL: configService.get('KAKAO_CALLBACK_URL'),
    });
  }

  async validate(accessToken: string, refreshToken: string, profile: any) {
    const email = profile._json.kakao_account.email;
    const nickname = new Date().getTime().toString(36); // 랜덤 닉네임 생성

    // 기존에 가입한 사용자인지 확인
    let user = await this.usersRepository.findOne({ where: { email } });
    // 없는 사용자면 데이터베이스에 사용자 정보 추가
    if (!user) {
      user = await this.usersRepository.save({
        email,
        // 빈 문자열로 설정해도 이메일로 빈 이메일로 일반 로그인 할 수 없음
        // PassportStrategy에서 비밀번호로 빈 문자열을 받지 못하게 되어 있어서
        password: '',
        nickname,
      });
    }

    return user;
  }
}
  • Strategy에서 해당 사용자가 있는지 검증을 하고 간단한 회원 가입을 진행함

  • 그리고 데이터베이스에 사용자 정보를 저장할 때 비밀번호로는 빈 문자열을 줌

  • 빈 문자열을 줘도 일반 로그인에서 사용하는 AuthGuard(’jwt’)의 PassportStrategy에서 비밀번호로 빈 문자열을 허용하지 않음

  • 그렇기에 일반 로그인에서 소셜 이메일과 빈 문자열 비밀번호로 로그인이 불가능함

  • 가드로 위 카카오 Strategy를 사용하기 위해서 카카오 가드를 만들어 줌

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

@Injectable()
export class KakaoAuthGuard extends AuthGuard('kakao') {}
  • 컨트롤러에서는 아래와 같이 가드 데코레이터를 이용해서 사용
import { Body, Controller, Get, Post, Req, Res, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { SignUpDto } from './dto/sign-up.dto';
import { SignInDto } from './dto/sign-in.dto';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { KakaoAuthGuard } from './utils/kakao.guard';

@ApiTags('인증')
@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}
  
  /**
   * 로그인
   * @param signInDto
   * @returns
   */
  @UseGuards(AuthGuard('local'))
  @Post('/sign-in')
  async signIn(@Req() req: any, @Body() signInDto: SignInDto) {
    return await this.authService.signIn(req.user);
  }

  /**
   * 카카오 로그인
   * @param req
   * @returns
   */
  @UseGuards(KakaoAuthGuard)
  @Get('/kakao')
  async kakaoSignIn(@Req() req: any, @Res() res: any) {
    console.log('controller : ', req.user);
    const { accessToken, refreshToken } = await this.authService.signIn(req.user);
    return res.send({ accessToken, refreshToken });
  }

}


📌 Tomorrow's Goal

✏️ 버블(Bubble.io)를 이용한 프론트엔드 공부

  • 내일은 버블을 이용해서 프론트엔드 구현하는 방법에 대해서 공부할 예정

  • 오늘 남은 시간동안 이것 저것 테스트 해봤는데, 생각보다 연결하고 신경써야 할게 많았음

  • 특히나 API 연결은 되었으나 그 API를 동작시키고 반환되는 값을 어떻게 가져와야 할지 찾는 중임

  • 이것만 해결되면 그래도 조금은 프론트엔드와 백엔드의 값 이동이 자유로울 것 같음



📌 Today's Goal I Done

✔️ 카카오 소셜 로그인 API 구현

  • 오늘은 Passport Strategy를 이용한 카카오 소셜 로그인을 구현함

  • 기존에 있던 Local Strategy를 많이 참고함

  • kakao developers에서 필요한 ID과 키를 받아서 .env에 저장함

  • 매 프로젝트마다 다른 분들이 작업하던 기능인데 실제로 구현해보니 생각보다 재밌었음

  • 그리고 동작 순서와 원리를 알면 생각보다 쉽게 구현할 수 있음


profile
조금씩 정리하자!!!

0개의 댓글