[React] 구글 소셜 로그인에 커스텀 버튼 사용하기

규바·2024년 2월 18일
1

@react-oauth/google를 활용할 때 커스텀한 이미지를 버튼을 사용하고자 함

https://react-oauth.vercel.app/ 를 먼저 참고하세요!!

상황

아래 방법을 이용하면 로그인 처리까지 초간단하나 버튼을 커스텀해서 사용할 수 없고 지정된 타입만을 사용할 수 밖에 없음

import { GoogleLogin } from '@react-oauth/google';

<GoogleLogin
  onSuccess={credentialResponse => {
    console.log(credentialResponse);
  }}
  onError={() => {
    console.log('Login Failed');
  }}
/>;

하지만 난 아래와 같은 버튼 이미지를 로그인 버튼으로 쓰고 싶었다

해결

따라서 custombutton으로 사용가능한 Implicit flow 방법으로 진행

import { useGoogleLogin } from '@react-oauth/google';

const login = useGoogleLogin({
  onSuccess: tokenResponse => console.log(tokenResponse),
});

<MyCustomButton onClick={() => login()}>Sign in with Google 🚀</MyCustomButton>;

<GoogleLogin/>은 바로 사용자 정보가 담긴 token을 credential에 담아 발급해줌
하지만 useGoogleLogin 을 사용하면 access_token을 가지고 다시 Google에 요청해서 사용자 정보를 가져와야 한다.

리액트 코드

import React from 'react';
import google from './img/google.png';  //사용하려는 커스텀 이미지
import Cookies from "js-cookie";
import axios from 'axios';
import { useGoogleLogin } from '@react-oauth/google';
import { GoogleOAuthProvider } from "@react-oauth/google";


const GoogleLoginButton = () => {
    const signIn = useGoogleLogin({
        onSuccess: (res) => { 
            axios.post('http://localhost:8080/auth/login', {
                access_token: res.access_token,
            })
            .then(response => {
            	Cookies.set('accessToken', response.data.token);
                console.log(response);
            })
            .catch(error => {
                console.log(error);
            });
        },
        onError: (error) =>{ console.log(error);}
    });

    return (
        <div onClick={() => signIn()}>
            <img src={google} alt="Login with Google" style={{ cursor: 'pointer' }} />
        </div>
    );
};

const LoginPage = () => {
    const clientId = 'GCP 프로젝트에서 가져온 clientId(env로 따로 관리하는 게 좋을 듯!)';

    return (
        <GoogleOAuthProvider clientId={clientId}>
            <GoogleLoginButton />
        </GoogleOAuthProvider>
    );
};

export default LoginPage;

useGoogleLogin이 성공하면 axios를 이용해 서버에 보내주었다.

서버 (스프링부트)

리액트에서 넘어오는 토큰 받아오는 컨트롤러는 생략..

    public static ResponseEntity<String> requestUserInfo(String accessToken) {
        RestTemplate restTemplate = new RestTemplate();

        String GOOGLE_USERINFO_REQUEST_URL="https://www.googleapis.com/oauth2/v1/userinfo";

        //header에 accessToken을 담는다.
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization","Bearer "+ accessToken);

        //HttpEntity를 하나 생성해 헤더를 담아서 restTemplate으로 구글과 통신하게 된다.
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity(headers);
        ResponseEntity<String> response= restTemplate.exchange(GOOGLE_USERINFO_REQUEST_URL, HttpMethod.GET,request,String.class);
        return response;
    }

과정

https://www.googleapis.com/oauth2/v1/userinfo의 헤더에 accessToken을 담아 전송하면(RestTemplate의 exchange 사용)
아래와 같이 user 정보가 넘어오게 된다.

이를 활용해서 회원가입 처리하고, 토큰을 만들어 반환하였다.

그리고

콘솔 창에 Cross-Origin-Opener-Policy policy would block the window.closed call. 가 발생하지만 진행하는데 문제는 없고 검색해봐도 외국 개발자들도 버그인가보다~ 하고 있더라.

혹시 부족하거나 잘못된 정보가 있다면 친절히 알려주시면 감사하겠습니다!!

참고:
https://www.npmjs.com/package/@react-oauth/google
https://react-oauth.vercel.app/
https://github.com/MomenSherif/react-oauth/issues/12#issuecomment-1131408898

profile
그때그때 학습하고 있는 내용을 올려요

0개의 댓글