Google 로그인에 대해 알아보기 전에, REST API를 활용한 소셜 로그인 과정에 대해 먼저 알아보려고 한다.
먼저 카카오 공식문서, 구글 공식문서를 확인한 후 블로그를 읽어보는 것을 추천한다!
개발 환경
- Front-end: React
- Back-end: Spring Boot

구글이든 카카오든 소셜 로그인 과정은 거의 유사하다. 처음 마주치면 이해도 안 되고 어려운 내용들인 것 같은데 딱 한 번만 이해하면 특히 Front-end 파트에서는 어려움이 없을 듯하다. 위의 다이어그램을 함께 확인하면 이해가 조금 더 쉬울 것이다. 내가 그랬다!
웹이나 앱에서 로그인 할 때 카카오로 계속하기, 구글로 계속하기 등의 소셜 로그인 버튼을 어렵지 않게 확인할 수 있다. 이 버튼을 눌렀을 때 카카오나 구글에서 제공하는 url로 페이지를 이동해 사용자의 계정으로 로그인하고 앱 사용 등록에 대해 동의를 받는다.
사용자가 카카오나 구글 로그인에 성공하면, 서비스에 등록된 redirect_uri로 페이지가 이동하면서 인가 코드 또는 액세스 토큰이 도착할 것이다.
주소창에서 인가 코드 또는 액세스 토큰을 추출한 후, 이를 body에 담아 백엔드의 api로 POST 요청을 보낸다.
백엔드에서는 프론트엔드로부터 받은 인가 코드 또는 액세스 토큰과 redirect_uri와 함께 카카오나 구글에 사용자의 정보를 요청한다.
카카오나 구글에서 백엔드의 요청을 토대로 유효성 검증 과정을 거쳐 액세스 토큰을 전송한다.
액세스 토큰을 이용해 유저 정보를 받은 후, 유저 정보가 있다면 JWT 토큰을 발행하고(로그인), 유저 정보가 없다면 새로운 유저 정보를 DB에 등록(회원가입) 과정을 거친다.
3번 과정에서 프론트엔드의 POST 요청의 response로 액세스 토큰과 함께 유저 정보를 전달한다.
프론트엔드는 토큰과 유저 정보를 받아 로그인/회원가입 처리 후 필요에 따라 이를 저장하기도 한다.
그렇다면 본격적으로 구글 로그인 과정을 살펴보자.
구글 클라우드 콘솔에 접속해서 새 프로젝트를 생성한다.

프로젝트 생성 후, API 및 서비스 탭의 OAuth 동의 화면을 클릭해 이동한다.

User Type은 외부로 설정하고, 나머지 OAuth 동의 화면은 필수 입력값만 입력한다.

사용자의 동의를 받은 후 구글로부터 어떤 정보를 받아올지 선택한다. email과 사용자 정보를 받아올 것이기 때문에 위의 두 개를 선택하였다.

다음으로, 사용자 인증 정보로 이동한다.

사용자 인증 정보 만들기를 선택하고 OAuth Client ID를 생성한다.

애플리케이션 유형은 웹 애플리케이션으로 설정한다.

승인된 리디렉션 URI에 Front-end의 리디렉션 URI를 입력한다. (백엔드와는 무관하다!)
로컬, 배포 버전을 모두 입력해야 한다.

완료하면 OAuth Client ID가 발급된다.

이 과정을 놓치기 쉬운데, API 라이브러리 탭으로 이동하여 Google+ API를 반드시 추가해야 한다!

다음으로 Front-end에서 필요한 과정을 알아보자.
다시 한 번 이야기하지만 작업 전에 반드시 공식문서를 확인하는 것이 좋다.
로그인 화면에서 "구글로 계속하기" 버튼을 클릭했을 때 실행할 이벤트 핸들러 함수를 정의한다.
다음 두 가지를 미리 환경변수(.env 파일)에 등록한다.
GOOGLE_CLIENT_ID: 1-5에서 발급 받은 OAuth Client IDGOOGLE_REDIRECT_URI: 1-5에서 승인된 리디렉션 URI에 등록한 Front-end의 URIconst handleGoogleLogin = () => {
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
const GOOGLE_REDIRECT_URI = import.meta.env.VITE_GOOGLE_REDIRECT_URI;
window.location.href = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${GOOGLE_CLIENT_ID}&redirect_uri=${GOOGLE_REDIRECT_URI}&response_type=token&scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile`;
};
...
<LoginTypeButton type="google" onClick={handleGoogleLogin} />
...
자세한 사항은 다음과 같다. 아래는 보기 쉽게 편집한 버전이다!
GOOGLE_CLIENT_ID: 1-5에서 발급 받은 OAuth Client IDGOOGLE_REDIRECT_URI: 1-5에서 승인된 리디렉션 URI에 등록한 Front-end의 URIresponse_type: 구글은 액세스 토큰 방식을 사용하므로 token으로 지정scope: 요청할 사용자의 정보 범위로, 다음 두 가지 주소를 입력https://www.googleapis.com/auth/userinfo.emailhttps://www.googleapis.com/auth/userinfo.profilewindow.location.href =
`https://accounts.google.com/o/oauth2/v2/auth?
client_id=${GOOGLE_CLIENT_ID}
&redirect_uri=${GOOGLE_REDIRECT_URI}
&response_type=token
&scope=
https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile`;
2-1의 과정을 거치면 다음과 같은 화면을 볼 수 있다.
| 구글 로그인 버튼 클릭 | 구글 계정 선택 | 정보 제공 동의 |
|---|---|---|
![]() | ![]() | ![]() |
서비스 이용 등록을 마치면, 브라우저의 주소가 설정한 redirect_uri로 이동되며, 구글의 경우 redirect_uri와 해시태그 # 뒤쪽으로 access_token, 토큰 타입, 만료 시간, 유효 범위 등의 정보들이 도착한다.
http://localhost:5173/user/auth/google/callback#access_token=ya29.a0ARW5m76g2N0C9-wp4bgG3hz_8KnWdyPmqZVFVltPBjHYlwkJYHQfDks6VxgbSH55gPZ9sLUeTkj2d2XNZYMuveEQAa3CG8GHHQ0IRBzQk5rOtSG7BCGv-zyNBHUIAeECFIkQxKX3i9QBp3vXkY7xaPx1nDhP8SeC8e_uV3RraCgYKAQgSARISFQHGX2MigUK7Bb3r6eVkPY8uo19jyA0175&token_type=Bearer&expires_in=3599&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.profile%20openid%20https://www.googleapis.com/auth/userinfo.email&authuser=0&prompt=consent
# 이후의 주소를 파싱한 후, access_token을 추출한다.
const parsedHash = new URLSearchParams(window.location.hash.substring(1));
const accessToken = parsedHash.get('access_token');
추출한 access_token을 body에 담아 백엔드 api로 POST 요청을 보낸다.
const handleLogin = async (accessToken: string) => {
try {
const response = await fetch(
`백엔드 API 주소`,
{
method: 'POST',
body: JSON.stringify({
accessToken,
}),
},
);
const data = await response.json();
console.log(data);
} catch (err) {
console.error(err);
}
};
백엔드 처리
백엔드에서는 프론트엔드에서 넘어온
accessToken을 이용해 구글 서버에 사용자의 정보를 요청한다.
엔드포인트 :https://www.googleapis.com/oauth2/v1/userinfo?access_token=${accessToken}
정보를 받은 뒤 DB에 로그인/회원가입 처리를 진행하고, JWT 토큰을 발급하면 된다.
우리 프로젝트의 경우 DB에 정보가 있으면 로그인, 없으면 회원의 추가 정보 입력으로 이동하는 방식으로 개발하였다.
백엔드에서 엔드포인트로 정보를 요청하면, 다음과 같은 정보들을 받아볼 수 있다.

이 정보를 바탕으로 로그인/ 회원가입 처리를 진행하고, JWT 토큰을 발급하면 된다!
이제 소셜 로그인 마스터 완료!