학습 출처 :

https://medium.com/@nielsmeima/auth-in-nest-js-and-angular-463525b6e071

 

Authorize User

- 소셜 로그인(Google)

Authenticate User

- Json Web Tokens(JWTs)

 

튜토리얼 순서

1. BE with Nest.js, Google OAuth And JWT

1-1. NestJs 프로젝트 생성

$ npm i -g @nestjs/cli              # nest.js cli 전역 설치
$ mkdir tutorial && cd tutorial     # 프로젝트 폴더 생성
$ nest new back-end && cd back-end  # nest new 명령어를 통한 nest.js 프로젝트 신규 생성

1-2. NestJs 테스트

$ npm run start:dev	         # Nest.js 서버 실행 명령어
$ curl http://localhost:3000 # 테스트
$ Hello World!

1-3. 'Auth' 관련 모듈, 컨트롤러, 서비스 생성

$ nest generate module auth # nest generate 명령어를 통한 모듈 생성
$ nest generate controller auth # nest generate 명령어를 통한 컨트롤러 생성
$ nest generate service auth/auth # nest generate 명령어를 통한 서비스 생성

1-4. 인증 관련 외부 라이브러리 설치

$ npm i --save @nestjs/passport passport passport-google-oauth20

1-5. Auth 폴더 내 google.strategy.ts 파일 생성

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

@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
  constructor() {
    super({
      clientID: 'CLIENT_ID', // CLIENT_ID
      clientSecret: 'CLIENT_SECRET', // CLIENT_SECRET
      callbackURL: 'http://localhost:3000/auth/google/callback',
      passReqToCallback: true,
      scope: ['profile'],
    });
  }
  // @nestjs/passport PassportStrategy를 상속
  // passport-google-oauth20 Strategy 사용
  // Strategy의 이름은 'google'로 지정
  // validate 함수 내에서, 성공적인 google 로그인에 대한 유효성 검증
  // google에서 보내주는 'profile' 정보만 로그로 기록
 

  async validate(
    request: any,
    accessToken: string,
    refreshToken: string,
    profile,
    done: any,
  ) {
    try {
      console.log(profile);

      const jwt = 'placeholderJWT';
      const user = {
        jwt,
      };
      done(null, user);
    } catch (err) {
      console.error(err);
      done(err, false);
    }
  }
}

1-6. AuthModule 내 GoogleStrategy provider로 등록

import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { GoogleStrategy } from './google.strategy';

@Module({
  controllers: [AuthController],
  providers: [
    AuthService,
    GoogleStrategy // provider 등록
  ]
})
export class AuthModule {}

1-7. Google에 의해 제공되는 Credential과 함께 OAuth2 Strategy를 구성하기

(Credential에는 CLIENT_ID와 CLIENT_SECRET이 포함됨)

더보기

Application 등록하는 과정이 필요하다.

1. 접속 :  https://console.developers.google.com

2. New Project 생성 (application 이름으로 주로 사용)

3. Google+ API 서비스 활성화(사용)으로 변경

4. https://console.developers.google.com에서 좌측 OAuth 동의화면으로 이동 (최초 1회)

- 앱 이름, 앱 로고이미지, 홈페이지 도메인 정보, 개인정보처리방침, 서비스 약관 등을 기입한다.

- 범위는 "추가"를 선택하고, email, profile 체크

- 앱이 dev 버전일 경우, 테스트 google 계정을 등록한 경우에만 서비스 이용이 가능하다.

(prod 버전일 때, 인증하면 모든 사람이 이용 가능)

5. https://console.developers.google.com에서 좌측 사용자 인증 정보(credential)로 이동

- "사용자 인증 정보 만들기" 선택 후, OAuth 클라이언트 ID

- 어플리케이션 유형은 "Web Application"으로 선택

- 승인된 자바스크립트 원본 항목(Google 인증을 요청할 root 웹 주소)

> http://localhost:3000 (개발용으로 로컬 BE URL추가, 추후 실제 요청 BE URL 주소로 바꾸어 주어야 함)

- 승인된 리디렉션 URI(사용자가 Google에서 승인을 받은 후, 리디렉션될 주소)

> http://localhost:3000/auth/google/callback

(google은 callback url로 리다이렉트 시킨 후, 성공적으로 로그인된 사용자 정보도 넘겨 준다.)

6. "생성" 완료

7. 생성된 ClientID와 ClientSecret이 BE 소스 내 google.strategy.ts 파일 상에서 사용하여, passport-google-oauth20 전략에 사용한다.

(주의 사항. ClientID와 ClientSecret을 어플리케이션 단에 바로 쓰지 않고, 꼭 환경 변수를 사용할 것, Nest.js의 configService를 사용하는 것이 안전하다)

 

 

### 아키텍처

Google Login 로직

  • FE 가 BE로 요청
  • 사용자는 로그인하고 Google은 사용자 정보와 함께 BE를 호출
  • BE가 사용자 정보를 처리(회원가입/로그인 + JWT 토큰 생성)
  • BE가 JWT와 함께 FE로 사용자를 redirect시킴
  • FE는 JWT를 등록 후, BE API 호출 시, 요청 header에 Token을 사용함

 

### 사용되는 외부 라이브러리

  • @nestjs/passport
  • passport
  • passport-google-oauth20

1-8. AuthController 작성하기

import { Controller, Get, UseGuards, Res, Req } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller('auth')
export class AuthController {

    @Get('google')
    @UseGuards(AuthGuard('google'))
    googleLogin()
    {
        // initiates the Google OAuth2 login flow
    }

    @Get('google/callback')
    @UseGuards(AuthGuard('google'))
    googleLoginCallback(@Req() req, @Res() res)
    {
        // handles the Google OAuth2 callback
        const jwt: string = req.user.jwt;
        if (jwt)
            res.redirect('http://localhost:4200/login/success/' + jwt);
        else 
            res.redirect('http://localhost:4200/login/failure');
    }

}

- 위에서 작성한 GoogleStrategy가 Guard 형식으로 사용됨

$ npm i --save jsonwebtoken # 실제 jwt token 생성을 위해 설치

 

2. FE with Angular, Material and NgRx

 

 

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기