songin.dev님의 블로그

Social login 중복되는 API 통합 본문

Developer/Backend

Social login 중복되는 API 통합

songin.dev 2023. 3. 25. 09:39
728x90

기존 코드

google, kakao, naver 반복되는 코드 발생!

import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Request, Response } from 'express';
import { User } from '../users/entities/user.entity';
import { UserService } from '../users/user.service';
import { AuthService } from './auth.service';

interface IOAuthUser {
  user: Pick<
    User,
    | 'email'
    | 'password'
    | 'name'
    | 'nickname'
    | 'gender'
    | 'birthday'
    | 'mobile'
    | 'profileImageUrl'
    | 'snsId'
    | 'snsType'
    | 'snsProfile'
  >;
}

@Controller()
export class AuthController {
  constructor(
    private readonly authService: AuthService,
    private readonly userService: UserService,
  ) {}

  @Get('/login/google')
  @UseGuards(AuthGuard('google'))
  async loginGoogle(
    @Req() req: Request & IOAuthUser, //
    @Res() res: Response,
  ) {
    let user = await this.userService.findOne({ email: req.user.email });
    if (!user) {
      user = await this.userService.create({
        email: req.user.email,
        hashedPassword: req.user.password,
        name: req.user.name,
        nickname: req.user.nickname,
        gender: req.user.gender,
        birthday: req.user.birthday,
        mobile: req.user.mobile,
        profileImageUrl: req.user.profileImageUrl,
        snsId: req.user.snsId,
        snsType: req.user.snsType,
        snsProfile: '',
      });
    }
    this.authService.setRefreshToken({ user, res });
    res.redirect(
      'http://localhost:5500/main-project/frontend/login/index.html',
    );
  }

  @Get('/login/naver')
  @UseGuards(AuthGuard('naver'))
  async loginNaver(
    @Req() req: Request & IOAuthUser, //
    @Res() res: Response,
  ) {
    let user = await this.userService.findOne({ email: req.user.email });
    if (!user) {
      user = await this.userService.create({
        email: req.user.email,
        hashedPassword: req.user.password,
        name: req.user.name,
        nickname: req.user.nickname,
        gender: req.user.gender,
        birthday: req.user.birthday,
        mobile: req.user.mobile,
        profileImageUrl: req.user.profileImageUrl,
        snsId: req.user.snsId,
        snsType: req.user.snsType,
        snsProfile: req.user.snsProfile,
      });
    }
    this.authService.setRefreshToken({ user, res });
    res.redirect(
      'http://localhost:5500/main-project/frontend/login/index.html',
    );
  }

  @Get('/login/kakao')
  @UseGuards(AuthGuard('kakao'))
  async loginKakao(
    @Req() req: Request & IOAuthUser, //
    @Res() res: Response,
  ) {
    let user = await this.userService.findOne({ email: req.user.email });
    if (!user) {
      user = await this.userService.create({
        email: req.user.email,
        hashedPassword: req.user.password,
        name: req.user.name,
        nickname: req.user.nickname,
        gender: req.user.gender,
        birthday: req.user.birthday,
        mobile: req.user.mobile,
        profileImageUrl: req.user.profileImageUrl,
        snsId: req.user.snsId,
        snsType: req.user.snsType,
        snsProfile: req.user.snsProfile,
      });
    }
    this.authService.setRefreshToken({ user, res });
    res.redirect(
      'http://localhost:5500/main-project/frontend/login/index.html',
    );
  }
}

최종 코드!

클래스 안에 선언된 메서드(함수)는 function, 화살표 함수 등을 선언하지 않음.
socialLogin 메서드에 중복되는 코드를 담고, google, kakao, naver에서 각각 this.socialLogin 으로 불러와서 사용!

import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Request, Response } from 'express';
import { User } from '../users/entities/user.entity';
import { UserService } from '../users/user.service';
import { AuthService } from './auth.service';

interface IOAuthUser {
  user: Pick<
    User,
    | 'email'
    | 'password'
    | 'name'
    | 'nickname'
    | 'gender'
    | 'birthday'
    | 'mobile'
    | 'profileImageUrl'
    | 'snsId'
    | 'snsType'
  >;
}

@Controller()
export class AuthController {
  constructor(
    private readonly authService: AuthService,
    private readonly userService: UserService,
  ) {}

  @Get('/login/google')
  @UseGuards(AuthGuard('google'))
  async loginGoogle(
    @Req() req: Request & IOAuthUser, //
    @Res() res: Response,
  ) {
    this.socialLogin(req, res);
  }

  @Get('/login/naver')
  @UseGuards(AuthGuard('naver'))
  async loginNaver(
    @Req() req: Request & IOAuthUser, //
    @Res() res: Response,
  ) {
    this.socialLogin(req, res);
  }

  @Get('/login/kakao')
  @UseGuards(AuthGuard('kakao'))
  async loginKakao(
    @Req() req: Request & IOAuthUser, //
    @Res() res: Response,
  ) {
    this.socialLogin(req, res);
  }

  async socialLogin(req, res) {
    let user = await this.userService.findOne({ email: req.user.email });
    if (!user) {
      user = await this.userService.create({
        email: req.user.email,
        hashedPassword: req.user.password,
        name: req.user.name,
        nickname: '',
        gender: '',
        birthday: '',
        mobile: '',
        profileImageUrl: '',
        snsId: req.user.snsId,
        snsType: req.user.snsType,
      });
    }
    this.authService.setRefreshToken({ user, res });
    res.redirect(
      'http://localhost:5500/main-project/frontend/login/index.html',
    );
  }
}
반응형

'Developer > Backend' 카테고리의 다른 글

서류 합격 후 코딩테스트 과제 후기  (1) 2023.04.03
Comments