[NestJS] - 20. 인증과 인가 - OAuth2 Google 소셜 로그인

2023. 3. 5. 02:05
반응형

 

많은 웹 서비스들을 보면 페이스북, 카카오, 네이버, 구글 등으로 소셜 로그인을 지원하는 것을 볼 수 있다.

이렇게 다른 믿을만한 플랫폼에 인증을 대신 맡기는 것을 OAuth 인증이라고 하는데

이번 포스팅에서는 구글 OAuth 인증에 대해서 알아보도록 하자.

https://sjh9708.tistory.com/46

 

[Web] 인증과 인가 - JWT 토큰 인증

앞 포스팅에서 세션 방식의 인증과, 성능 개선을 위한 방법들에 대해서 다루어 보았었는데 이번에는 언급했던 토큰 인증 방식에 대해서 알아보려고 한다. 토큰 인증 세션 인증 방식과 달리 인증

sjh9708.tistory.com

 


패키지 설치

 

yarn add passport-google-oauth20

Google OAuth의 Passport Strategy를 사용하기 위해 다음의 패키지를 설치하자.

 


구글 계정 세팅

구글의 OAuth를 이용하기 위해서는 Application 프로젝트를 생성하고 App에서 이용할 수 있도록 세팅을 해주어야 한다..

 

 

GCP 프로젝트 생성

GCP Console에서 OAuth를 이용하기 위해서 프로젝트를 생성한다.

 

 

 

사용자 인증 정보 설정하기

OAuth를 이용할 때 사용할 클라이언트 ID와 Secret을 발급받기 휘애서 사용자 인증 정보 만들기 -> OAuth 클라이언트 ID 를 만든다.

위에서 만든 후 발급받은 ID와 Secret을 App에서 사용할 것이다.

 

클라이언트 ID를 만들 때 승인돤 리디렉션 URI 항목에 소셜 로그인 성공 후 로그인을 처리할 API 주소를 입력해야 한다.

 

 

 

Google People API 사용 설정

로그인 시 사용자의 정보를 받아오기 위해서 People API(people.googleapis.com)를 사용 추가해준다.

 

 

 

 


Google Passport Strategy 만들기

 

 jwt-oauth-google.strategy.ts

import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-google-oauth20';

//Google Strategy 사용
export class JwtGoogleStrategy extends PassportStrategy(Strategy, 'google') {
  constructor() {
    super({
      clientID: process.env.GOOGLE_AUTH_CLIENT, //ID
      clientSecret: process.env.GOOGLE_AUTH_SECRET, //PWD
      callbackURL: 'http://localhost:3000/auth/login/google', //성공 시 URL
      scope: ['email', 'profile'], //성공시 받을 데이터
    });
  }

  validate(accessToken, refreshToken, profile) {
    console.log(profile);
    return {
      email: profile.emails[0].value,
      name: profile.displayName,
    };
  }
}

구글 인증을 위한 Strategy를 하나 생성해주었다.

  • 이번엔 Strategy를 google-oauth20에서 import해주었다. 즉, Strategy의 종류가 이전에 사용하던 종류와는 다르다.
  • 생성자 : GCP에서 발급받은 ID와 Secret을 입력하고, callbackURL에 구글 로그인 성공 시 처리할 URL을 입력해준다. 해당 URL은 아까 승인된 URI 리다이렉션 목록에 있어야 한다. scope에는 로그인 성공 시 구글 측으로부터 받을 데이터를 입력해준다.
  • validate에서는 accessToken, refreshToken, profile을 성공 시 구글측으로부터 받으며, 해당 Strategy Guard를 사용할 때 인가 성공 시 넘겨줄 데이터들을 작성한다.

 

 

 


Google 로그인 API 만들기

 

auth.controller.ts

  @UseGuards(AuthGuard('google'))
  @Get('login/google')
  async loginGoogle(@Req() req: Request & IOAuthUser, @Res() res: Response) {
    //1. 가입확인
    let user = await this.userService.findOne(req.user.email);
    //2. 회원가입
    if (!user) {
      const input = {
        email: req.user.email,
        password: 'OAuth',
        name: req.user.name,
        age: 0,
      } as CreateUserInput;

      user = await this.userService.create(input);
    }
    //3. 로그인
    this.authService.setRefreshToken({ user, res });
    res.redirect(
      'http://localhost:5500/09_Authorization/09-04-oauth/frontend/success.html',
    );
  }
  • 앞에서 만든 Google Strategy Guard를 사용하였다. 이제 해당 API에 접근하기 전에 구글 로그인이 성공해 있어야 한다.
  • 구글의 인가를 통과하면 해당 API가 실행되게 된다.
  • 해당 코드에서는 내부 회원가입이 되어있지 않으면 구글에서 제공받은 이메일과 이름으로 회원가입을 진행하고 있다. 용도에 맞게 회원가입이 되어있지 않으면 회원가입 폼으로 이동시키는 등 작성하기 나름이다.
  • 회원가입 완료 후 로그인 처리를 위해서 Refresh Token을 발급하였다. 이제 클라이언트는 Refresh Token으로 Access Token을 발급받을 수 있다.
  • 클라이언트에서 /auth/login/google 요청을 하게 되면 OAuth에 의해서 구글 로그인 창으로 Redirect되게 된다. API 완료 시 클라이언트가 어떤 페이지로 전환할지를 res.redirect()로 설정해준다.

 

이제 구현된 OAuth 인증과 인가 과정을 정리해보면

1. 클라이언트의 구글 로그인 요청

2. 클라이언트는 구글 로그인 페이지로 이동한다.

3. 로그인 성공 시 구글은 인가를 위한 Google Access Token을 발급한다.

4. 발급받은 토큰을 이용하여 AuthGuard('google')을 뚫었다면, 서비스의 회원가입이 되어있지 않았다면 가입시킨다.

5. Refresh Token을 발급한다.

6. 클라이언트는 로그인 성공 화면으로 이동시킨다.

 

 

 

 social-login.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>소셜로그인</title>
  </head>
  <body>
    <a href="http://localhost:3000/auth/login/google">구글로그인</a>
  </body>
</html>

클라이언트 측에서 구글 로그인 요청을 하려면 단지 이런 식으로 요청하면 된다.

반응형

BELATED ARTICLES

more