logo
github
Google OAuth 도입하기 (react-google-login)
January 29, 2022

🚨 주의 🚨
react-google-login 라이브러리는 현재 deprecated 되었다고 합니다


react-google-login 라이브러리

import GoogleLogin from 'react-google-login';

const responseGoogle = (res) => {
  console.log(res);
};

<GoogleLogin
  clientId="${clientId}"
  buttonText="구글로 계속하기"
  onSuccess={responseGoogle}
  onFailure={responseGoogle}
/>;

clientId는 필수, 나머지는 선택 사항 clientId는 구글 클라우드 플랫폼에서 발급받을 수 있고, .env에 환경 변수로 두는 게 좋다고 한다. onSuccess는 로그인 성공 시 실행되는 함수, onFailure는 실패 시 실행되는 함수를 주면 된다.


겪었던 에러들…

에러 1: redirect uri mismatch

Google Cloud Platform에서 승인된 자바스크립트 출처, 승인된 리다이렉션 URI에 http://localhost:3000/ 추가하면 됨!


에러 2: idpiframe_initialization_failed

{error: 'idpiframe_initialization_failed', details: "Not a valid origin for the client: http://localhos…egister this origin for your project's client ID."}
details: "Not a valid origin for the client: http://localhost:3000 has not been registered for client ID 1035419561052-bampb5j473a13bdvvsi7hq0q8s9ulaft.apps.googleusercontent.com. Please go to https://console.developers.google.com/ and register this origin for your project's client ID."
error: "idpiframe_initialization_failed"
{
  error: 'popup_closed_by_user';
}

크롬 설정 > 개인 정보 및 보안 > 인터넷 사용 기록 삭제 > 캐시된 이미지 및 파일 삭제 정확히 뭐 때문에 해결된 건진 모르겠는데 위 방법 덕분인 것 같다.


에러 3: Content-Type (400 (Bad Request))

계속 401 Unauthorized 오류가 떠서 머리를 쥐어뜯으며 한참을 고민했따… 구글링해 보니 withCredentials: true 옵션을 추가해야 하는 것 같았다… (아니었음)

그렇게 몇 시간을 삽질하다가 혜원이의 도움으로 원인을 찾았어요 내가 작성했던 axios instance 기본 설정 파일이 문제였음…

그 당시의 코드

import axios from 'axios';

const API = axios.create({
  baseURL: process.env.REACT_APP_API_PATH,
  headers: {
    'Content-Type': 'application/json',
  },
});

API.interceptors.request.use((config) => {
  const accessToken = localStorage.getItem('accessToken');
  accessToken && (config.headers.Authorization = `Bearer ${accessToken}`);

  return config;
});

export default API;

위에서 보다시피 기본적으로 헤더의 content type을 application/json 으로 설정했는데, idToken을 이용해 access token을 발급받을 때 필요한 형식은 x-www-form-urlencoded 이었다고 한다… ^^
Content type을 잘 확인하자!


결과적으로 구현한 코드

구글 로그인 성공 시 실행되는 함수 (onSuccess)

const onGoogleSignInSuccess = (res) => {
  const params = new URLSearchParams();
  params.append('idToken', res.tokenObj.id_token);

  const googleLogin = async () => {
    const res = await axios.post('요청 주소', params, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    });

    localStorage.setItem('accessToken', res.data.token.access);
    localStorage.setItem('refreshToken', res.data.token.refresh);
  };

  googleLogin();
};

과정은 다음과 같다. 사용자가 구글 계정 선택 → id token 발급 → id token을 이용하여 refresh token과 access token 발급

위에서 언급했던 에러3 때문에 URLSearchParams()를 이용하여 id token 값을 담아 보냈고, id token으로 발급받은 refresh token과 access token은 local storage에 저장했다.


로그인 버튼 커스텀

아래와 같이 작성하면 사진과 같은 기본 버튼이 나오는데, 나는 이를 커스텀해야 했기 때문에 추가로 코드를 작성해야 했다.

import GoogleLogin from 'react-google-login';

// 생략

return (
  <GoogleLogin
    clientId={process.env.REACT_APP_GOOGLE_API_KEY}
    onSuccess={onGoogleSignInSuccess}
  />
);


import styled from 'styled-components';
import GoogleLogin from 'react-google-login';

// 생략

return (
  <GoogleLogin
    clientId={process.env.REACT_APP_GOOGLE_API_KEY}
    onSuccess={onGoogleSignInSuccess}
    render={(renderProps) => (
      <GoogleButton onClick={renderProps.onClick}>
        <GoogleWrapper>
          <GoogleLogo src={google} />
          <GoogleText>구글로 계속하기</GoogleText>
        </GoogleWrapper>
      </GoogleButton>
    )}
  />
);

<GoogleButton/>, <GoogleWrapper>, <GoogleLogo/>, <GoogleText/>styled-components 를 이용하여 만든 컴포넌트들이다. 위의 코드처럼 render에 커스텀 버튼 코드를 작성하면 된다.

그럼 이렇게 원하는 대로 커스텀할 수 있다!

corinthionia
🍀 Winning Mentality💭 능동적인 사고를 통한 성장을 위해 노력합니다
© Joohyun Kim (김주현) Corinthionia