본문 바로가기
개발/리액트

리액트 구글 OAuth2 API를 이용한 로그인 구현

by ^..^v 2020. 5. 20.
728x90
반응형

#1 프로젝트 생성

c:\react> npx create-react-app login

 

 

#2 Visual Studio 프로젝트 추가

 

#3 Login.js 파일 생성

컴포넌트가 마운트되면 구글 SDK를 가져와서 auth2 기능을 초기화한다. 

 

OAuth 클라이언트 생성 및 클라이언트 ID 확인 방법은 "GCP OAuth 클라이언트 생성"을 참조하세요.

import React, { Component } from 'react';

class Login extends Component {

    constructor() {
        super();
        this.state = { token: '' };

    }

    // #1 컴포넌트 마운트 직후 호출
    componentDidMount() {
        this.googleSDK();
    }
    // #4 로그인 기능 구현
    login = () => {
        this.auth2.signIn().then(googleUser => {
            let profile = googleUser.getBasicProfile();
            console.log('Token || ' + googleUser.getAuthResponse().id_token);
            console.log('ID: ' + profile.getId());
            console.log('Name: ' + profile.getName());
            console.log('Image URL: ' + profile.getImageUrl());
            console.log('Email: ' + profile.getEmail());

            this.setState({ token: googleUser.getAuthResponse().id_token });
        });
    }

    // #5 로그아웃 기능 구현
    logout = () => {
        this.setState({ token: '' });
        this.auth2.disconnect();
    }

    googleSDK = () => {
        // #3 platform.js 스크립트 로드 후 gapi.auth2.init 함수 호출 및 로그인 버튼 기능 활성화
        window['googleSDKLoaded'] = () => {
            window['gapi'].load('auth2', () => {
                // https://developers.google.com/identity/sign-in/web/reference#gapiauth2initparams
                // https://developers.google.com/identity/sign-in/web/reference#gapiauth2clientconfig
                this.auth2 = window['gapi'].auth2.init({
                    client_id: 'GCP_OAUTH2_CLIENT_ID',
                    cookiepolicy: 'single_host_origin',
                    scope: 'profile email',
                });
            });
        }

        // #2 <script id="google-jssdk" src="https://.../platform.js?onload=googleSDKLoaded"></script> 태그를 문서에 추가
        //    스크립트 코드가 로드되면 googleSDKLoaded 호출
        (function (d, s, id) {
            var js, fjs = d.getElementsByTagName(s)[0];
            if (d.getElementById(id)) { return; }
            js = d.createElement(s); js.id = id;
            js.src = "https://apis.google.com/js/platform.js?onload=googleSDKLoaded";
            fjs.parentNode.insertBefore(js, fjs);
        }(document, 'script', 'google-jssdk'));
    }

    render() {
        return (
            <div className="row mt-5">
                <div className="col-md-12">
                    <h2 className="text-left">Google Login Demo</h2>
                    <div className="card mt-3">
                        <div className="card-body">
                            <div className="row mt-5 mb-5">
                                <div className="col-md-4 mt-2 m-auto ">
                                    {this.state.token ?
                                        <button className="logoutBtn loginBtn--google" onClick={this.logout}>Logout</button> :
                                        <button className="loginBtn loginBtn--google" onClick={this.login} ref="">Login with Google</button>
                                    }
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

export default Login;

 

#4 App.js에 Login 컴포넌트 추가

import React from 'react';
import './App.css';
import Login from './Login.js';

function App() {
  return (
    <div className="App">
      <Login />
    </div>
  );
}

export default App;

 

#5 index.css 파일에 구글 로그인 버튼 스타일 추가

.loginBtn {
    box-sizing: border-box;
    position: relative;
    margin: 0.2em;
    padding: 0 15px 0 46px;
    border: none;
    text-align: left;
    line-height: 34px;
    white-space: nowrap;
    border-radius: 0.2em;
    font-size: 16px;
    color: #FFF;
}

.logoutBtn {
  box-sizing: border-box;
  position: relative;
  margin: 0.2em;
  padding: 0 15px;
  border: none;
  text-align: left;
  line-height: 34px;
  white-space: nowrap;
  border-radius: 0.2em;
  font-size: 16px;
  color: #FFF;
}

.loginBtn:before {
    content: "";
    box-sizing: border-box;
    position: absolute;
    top: 0;
    left: 0;
    width: 34px;
    height: 100%;
}

.loginBtn:focus {
    outline: none;
}

.loginBtn:active {
    box-shadow: inset 0 0 0 32px rgba(0, 0, 0, 0.1);
}

.loginBtn--google {
    background: #DD4B39;
}

.loginBtn--google:before {
    border-right: #BB3F30 1px solid;
    background: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/14082/icon_google.png') 6px 6px no-repeat;
}

.loginBtn--google:hover,
.loginBtn--google:focus {
    background: #E74B37;
}

 

#6 테스트

토큰, 아이디, 이름, 프로필 사진, 이메일 정보가 콘솔에 출력되는 것을 확인

 

구글에서 가져온 정보를 저장하는 방법은 "구글 로그인 결과를 저장하는 REST API 제작"을 참고하세요.

728x90
반응형

댓글