(React) 프론트엔드에서 구글 로그인 API (Google OAuth 2.0) 도입하기

kidstone·2025년 2월 9일

외개인 프로젝트

목록 보기
9/10
post-thumbnail

들어가며

외개인 프로젝트의 로그인 기능을 고민하던 중, 우리는 자체 로그인 서비스 대신 구글 소셜 로그인 서비스를 제공하기로 결정했다. 외개인 서비스는 우리 학교의 학생들만 이용할 수 있기 때문에, 개인이 소유한 학교 구글 계정으로 로그인을 진행하면 자동으로 해당 학생임을 인증할 수 있다. 이에 따라 이번 포스팅에서는 프론트엔드 측면에서 Google OAuth 2.0 기능을 사용하는 방법과 그 과정에 대해 상세히 기록해보겠다.


OAuth 2.0이란?

OAuth 2.0은 인터넷 사용자들이 비밀번호를 공유하지 않고도 제3의 애플리케이션이 특정 서비스에 대한 접근 권한을 부여할 수 있도록 하는 인증 프레임워크다. 이를 통해 유저의 개인정보와 같은 자원에 대한 접근을 안전하게 제어할 수 있다. 즉, 제3의 애플리케이션 구글을 이용하여 외개인 서비스에 접근할 수 있는 것이다.

주요 구성 요소

  • Resource Owner: 해당 자원의 권한을 가진 사용자이다.(구글 계정 소유자)
  • Client: 리소스 소유자의 자원에 접근하려는 애플리케이션 (외개인 서비스)
  • Resource Server: 사용자의 개인정보를 가지고 있는 애플리케이션 회사 서버(Google)
  • Authorization Server: 권한을 부여해주는 서버. Authorization code와 AccessToken을 발급해준다.

OAuth 2.0을 사용하여 Google API에 액세스하기


위 사진은 로그인 과정이 전체적으로 역할들에 따라 어떤 흐름으로 가고 있는지 전반적으로 볼 수 있는 도식이다. 좀 더 자세히 설명해보겠다.

승인 사용자 인증 정보 만들기

구글 OAuth 2.0을 사용하여 Google API에 액세스하는 모든 서비스는 승인 사용자 인증 정보를 생성해야 한다. 아래의 경로를 들어가서 사용자 인증 정보를 만들 수 있다.
https://console.developers.google.com/apis/credentials?hl=ko

구글 OAuth 2.0을 사용하는 전반적인 방법과 과정은 아래의 링크에 상세히 기술되어있다.
https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow?hl=ko

구글 로그인 버튼

import React from 'react';
...
const LoginPage = () => {
	...
	const CLIENT_ID = process.env.REACT_APP_GOOGLE_AUTH_CLIENT_ID;
	const REDIRECT_URL = process.env.REACT_APP_SERVICE_URL;
	return (
		<>
			...
			<div className="px-[35px]">
				<Link
					to={`https://accounts.google.com/o/oauth2/v2/auth?
					client_id=${CLIENT_ID}
					&redirect_uri=${REDIRECT_URL}/callback
					&response_type=code
					&scope=https://www.googleapis.com/auth/userinfo.email`}
					style={{ borderColor: COLOR.gray200 }}
					className="border w-full h-[50px] rounded-[5px] flex items-center px-[23px] shadow-[1px_1px_4px_rgba(0,0,0,0.25)] hover:opacity-20"
				>
					<img
						className="mr-[60px]"
						src={GoogleIcon}
						alt="구글 로그인 아이콘"
					/>
					<StyledButtonText>Google로 계속하기</StyledButtonText>
				</Link>
			</div>
		</>
	);
};

export default LoginPage;
 ...

로그인 페이지다. 구글 로그인 버튼을 클릭하면 연결된 경로인 Google OAuth 2.0 서버 https://accounts.google.com/o/oauth2/v2/auth?로 리디렉션하게 된다. 이때 매개변수로는 client_id, redirect_uri, response_type, scope를 전달한다.

  • client_id: 애플리케이션의 클라이언트 ID. 승인 사용자 정보를 만들면 발급받을 수 있다.
  • redirect_uri: 인증 후 사용자가 리디렉션될 URI
  • response_type: 인증 서버가 클라이언트에 반환해야 할 응답의 유형. 보낼 값으로는 code와 token이 있다. code를 실어보내면, 인증 서버는 클라이언트에게 "승인 코드"를 반환한다. 클라이언트는 백엔드에게 승인 코드를 전달하고, 백엔드와 인증 서버의 서버 간의 통신을 통해 AccessToken이 전달되기 때문에 보안성이 높다. token을 실어보내면, 인증 서버는 클라이언트에게 직접 "액세스 토큰"을 URL의 해시 프래그먼트에 포함하여 반환한다. 이는 토큰이 URL에 포함되므로 보안성이 낮다. 일반적으로 code를 사용한다.
  • scope: 클라이언트가 요청하는 권한의 범위


리디렉션된 페이지이다. 이 곳에서 구글 계정을 이용해 로그인을 완료하면 아까 설정했던 redirect_uri로 이동하게된다.

리디렉션 경로에서 받은 Authorization code를 이용하여 AccessToken 발급받기

CallBack.jsx

import React, { useEffect } from 'react';
...

const CallBack = () => {
	const setAccessToken = useAuthStore((state) => state.setAccessToken);
	const setMyInfo = useMyInfoStore((state) => state.setMyInfo);
	const location = useLocation();
	const navigate = useNavigate();
	useEffect(() => {
		const queryParams = new URLSearchParams(location.search);
		const code = queryParams.get('code');
		const fetchData = async () => {
			try {
				const response = await API.get(
					`/api/v1/member/auth/google/callback?code=${code}`,
				);
				const accessToken = response.data.accessToken;
				const {
					email,
					gender,
					introduction,
					name,
					photoUrl,
					profileSetUpStatus,
					id,
				} = response.data;
				const myInfo = {
					email,
					gender,
					introduction,
					name,
					photoUrl,
					profileSetUpStatus,
					id,
				};
				setAccessToken(accessToken);
				setMyInfo(myInfo);
				API.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
				if (profileSetUpStatus) {
					navigate('/home');
				} else {
					navigate('/setting');
				}
			} catch (error) {
				navigate('/login');
			}
		};
		if (code) {
			fetchData();
		}
	}, []);
	return <div></div>;
};

export default CallBack;

redirect_uri로 설정했던 /callback 경로에 CallBack.jsx를 등록했다. 구글 로그인을 한 뒤에 /callback 경로로 이동되면 인증 서버에서 파라미터에 code를 첨부해서 리디렉트한다.


이 code를 이용해 백엔드에게 API 요청을 진행한다. 백엔드는 클라이언트로부터 받은 code를 이용해 인증 서버에 요청하여 AccessToken을 발급받는다. 이 토큰을 이용하여 리소스 서버로 유저 데이터를 요청하고, 동시에 우리 서버에 있는 해당 유저의 데이터들도 가져와서 한번에 클라이언트로 내려주고 있다. 내려받은 토큰과 유저 정보들은 전역 상태로 관리하였다.

이로써 구글 계정으로 로그인 성공!

profile
안녕하세요. 웹 프론트엔드 개발자 앞잡이 '꼬마돌' 입니다.

0개의 댓글