티스토리 뷰

IT

Social login 중복되는 API 통합

csongin 2023. 3. 25. 09:39

목차



    반응형

    기존 코드

    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',
        );
      }
    }
    반응형