구글 OAuth2.0 - Final Project

조상래·2021년 5월 2일
22

코드스테이츠

목록 보기
67/73

이번 프로젝트에서 구글 소셜로그인을 넣기로 했다. 코드스테이츠에서 OAuth 스프린트를 할 때 깃헙 OAuth를 이용한 소셜로그인을 가르쳐 주었고, 심화과제로 구글 소셜로그인을 구현을 하라고 했었는데 안했다. 그때 해둘걸 그랬다. 왜냐면, 생각보다 복잡하고 공식문서도 깃헙에 비해 조금 불친절해서 꽤나 애를 먹었기 때문이다.

1. 구글 클라우드 플랫폼

코드를 작성하기전에 구글 클라우드 플랫폼을 통해 프로젝트를 생성해야한다.

프로젝트 선택을 누르고 새 프로젝트를 눌러준다.

위와같은 화면이 나오면 원하는 이름을 설정한 후 만들기를 눌러준다.(이름 설정하는 모든 부분에선 중복되지않는 이름을 적는 것이 좋다고 봤다. 이유는 잘 모른다 ㅠㅠㅠ)

위와같이 홈으로 리다이렉트되고 대시보드가 나오는데 옆 네비게이션바에서 API 및 서비스 -> OAuth 동의 화면을 눌러준다.

위 화면이 나온다면 외부로 설정하고 만들기를 눌러준다.

앱 이름은 원하는 것(OAuth가 사용될 클라이언트 이름으로 설정하는 것이 가장 좋겠지?)으로 설정하면 된다.

사용자 지원 이메일은 문의 이메일이라고 보면된다. 만약 웹페이지를 운영한다면 개인 이메일을 대신 팀 대표 이메일을 만들어 사용하는 것이 좋을 것 같다.

앱 로고는 말그대로 제공되는 OAuth화면에 보여주고싶은 로고이다. 원하는 것으로 설정하면된다.

애플리케이션 홈페이지, 서비스 약관링크는 말 그대로 홈페이지 약관링크를 제공한다고 보면된다.

위처럼 우리가 소셜로그인을 할 때 자주보는 화면을 만드는 과정이라 생각하면된다. 저장 후 계속을 누르면, 범위 설정하는 화면으로 넘어간다.

이 부분은 사용자의 정보를 어느정도까지 받아오느냐를 결정하는 것이다. 나는 유저를 구분할 email/공개된 개인정보/openid 이정만 있으면 되기에 사진 처럼 선택해주었다. 그리고 저장 후 계속을 누르면 테스트 사용자 설정 화면이 나오는데 이는 게시상태를 테스트로 했을 때 테스트 사용자에 추가된 사람만 접근이 가능하도록 만드는 것이다. 개발중엔 팀원을 등록해주는게 좋을 듯 하다.

동의화면 설정이 완료되면

옆 메뉴에서 사용자 인증 정보를 누르고 OAuth 클라이언트 ID를 눌러 인증 정보를 설정한다.

앱 유형은 사용할 형태에 맞게 선택하면 된다.
이름은 아무거나 쓰면된다.
승인된 자바스크립트 원본엔 어떤 클라이언트에서 사용될지 주소를 넣으면된다
승인된 리디렉션URI엔 인증을 마친 후 리디렉션이 될 주소를 넣어주면 된다.

위와 같은 화면이 나오면 끝이다. 클라이언트 ID/비밀번호는 어디 잘 보관해주자!

코드작성 전 준비 완료!!

2. 코드작성

공식 문서상에서 액세스 토큰을 받는 방법이 설명되어있다. url은 'https://accounts.google.com/o/oauth2/v2/auth'로 요청을 하면 되고 필수 인자가 있는데 위에서 설정 해 뒀던 대로 넣어주면된다.

https://accounts.google.com/o/oauth2/v2/auth?client_id=클라이언트아이디&response_type=token&redirect_uri=https://localhost:3000&scope=https://www.googleapis.com/auth/userinfo.email

좀 많이 복잡하다... 변수를 사용하는 것이 정신건강에 좋을 것이다.

하나하나 뜯어서 설명하자면

  • client_id: 발급받은 클라이언트 아이디를 넣어주면된다.

  • response_type: 공식문서상 token으로 입력하라고 되어있다.

  • redirect_uri: 설정한 리다이렉트 링크로 넣는다. 만약 다르면 다르다고 말해준다.

  • scope: 스코프에 따라 받을 수 있는 정보가 달라지는데, 아까 위에서 범위를 설정했고 email까지 필요하니까 위처럼 설정해주었다.


    (공식문서 참고)

    이제 적용해보는 시간이다.

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {faGoogle} from '@fortawesome/free-brands-svg-icons';
import './App.scss';
import { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [ data, setData ] = useState(null);
  const google = <FontAwesomeIcon icon={faGoogle} size="10x"/>;
  const oAuthURL = 
  `https://accounts.google.com/o/oauth2/v2/auth?client_id=클라이언트아이디&
response_type=token&
redirect_uri=https://localhost:3000&
scope=https://www.googleapis.com/auth/userinfo.email`
  const oAuthHandler = () => {
    window.location.assign(oAuthURL);
  }

  useEffect( async () => {
    const url = new URL(window.location.href);
    const hash = url.hash;
    if (hash) {
      const accessToken = hash.split("=")[1].split("&")[0];
      await axios.get('https://www.googleapis.com/oauth2/v2/userinfo?access_token=' + accessToken, { 
        headers: { 
          authorization: `token ${accessToken}`, 
          accept: 'application/json' 
        }})
        .then(data => {
          console.log(data);
          setData(data);
      }).catch(e => console.log('oAuth token expired'));
    }
  }, [])

  return (
    <div>
      <button id="oAuthBtn" onClick={oAuthHandler}>
        {google}
        <div id="comment">구글 OAuth</div>
      </button>
    </div>
  );
}

export default App;

간단하게 테스트용 앱을 만들었다. 위는 전체 코드이고 밑에서 나눠서 설명할 예정이다.

먼저 작동 테스트를 해보자.

위 처럼 뜨면 성공한 것이다.

//생략
  const oAuthURL = 
  `https://accounts.google.com/o/oauth2/v2/auth?client_id=클라이언트아이디&
response_type=token&
redirect_uri=https://localhost:3000&
scope=https://www.googleapis.com/auth/userinfo.email`
  const oAuthHandler = () => {
    window.location.assign(oAuthURL);
  }
//생략

구글 로고를 눌렀을 때 작동되는 리디렉션 코드이다. 인증을 완료하면

다음과 같이 토큰이 같이 오는 것을 확인할 수 있다. 토큰을 추출해서 구글 api를 통해 정보를 요청하면 된다.

//생략
  useEffect( async () => {
    const url = new URL(window.location.href);
    //? hash를 떼어주고
    const hash = url.hash;
    if (hash) {
      //? 토큰만 떼어주면된다.
      const accessToken = hash.split("=")[1].split("&")[0];
      //? 토큰을 이용한 api 요청.
      await axios.get('https://www.googleapis.com/oauth2/v2/userinfo?access_token=' + accessToken, { 
        headers: { 
          authorization: `token ${accessToken}`, 
          accept: 'application/json' 
        }})
        .then(data => {
          setData(data);
      }).catch(e => console.log('oAuth token expired'));
    }
  }, [])
//생략

리다이렉트가 되면 useEffect가 작동할 것이고 그에 따라 요청을 하게 만들어주면 된다.

data를 console.log를 찍었을 때 이렇게 온다면 성공이다! 이제 이 정보를 이용해 렌더링을 하거나, 다른 작업을 하면된다.

profile
Codestates Full IM26기 수료

3개의 댓글

comment-user-thumbnail
2021년 11월 24일

선생님 좋은 글 감사합니다.

답글 달기
comment-user-thumbnail
2022년 1월 1일

안녕하세요 좋은 글 감사합니다!
다름이 아니라 리디렉션될때 저는 https로 받으면 ERR_SSL_PROTOCOL_ERROR라는 오류가 뜨고 http로 바꿔서 엑세스코드받으면 정상 렌더링되더라구요 혹시 이런 오류는 없으셨나요..? ㅠ

1개의 답글