이번에 사내에서 실시간 채팅 기능을 포함한 프로젝트를 진행하게 되었습니다. 여러 명의 사용자가 동시에 참여하고, 메시지를 주고받는 환경을 구현하다 보니, 자연스럽게 유저별 식별 정보가 필요해졌습니다.
이 과정에서 사내 구성원 모두가 사용하는 구글 워크스페이스(Google Workspace) 메일이 있다는 점에, 로그인 수단으로 Google 소셜 로그인을 도입하게 되었습니다.
이 글에서는 다음과 같은 내용을 중심으로 정리해보았습니다:
- Google OAuth 2.0의 기본 개념과 흐름
- React에서 Google 소셜 로그인 구현 방법
- 인증된 사용자만 접근할 수 있는 Protected Route 구성
1. Google OAuth 2.0의 기본 개념과 흐름
Google 소셜 로그인은 OAuth 2.0 프로토콜을 기반으로 작동합니다. OAuth 2.0은 사용자의 비밀번호를 직접 노출하지 않고, 제3자 애플리케이션(우리 서비스)이 사용자의 자원(이메일, 프로필 등)에 접근할 수 있도록 하는 권한 위임 방식의 인증 프로토콜입니다.
인증 흐름
- 사용자가 Google 로그인
- Google이 Authorization Code를 프론트에 전달
- 프론트는 이 코드를 백엔드로 전달
- 백엔드는 Google과 통신하여 이 코드로 access token + id token 획득
- 백엔드는 access token 또는 자체 발급한 세션 토큰을 프론트에 전달
2. React에서 Google 소셜 로그인 구현
@react-oauth/google 패키지를 사용하였습니다.
Google OAuth 클라이언트 ID 발급
Google Cloud Console에서 새 프로젝트를 만들고,
OAuth 2.0 클라이언트 ID를 생성합니다.
리디렉션 URI에는 로컬 개발용 주소(http://localhost:3000)를 등록해줍니다.
GoogleOAuthProvider로 App 감싸기
// index.js
import { GoogleOAuthProvider } from '@react-oauth/google';
<GoogleOAuthProvider clientId="발급받은-client-id">
<App />
</GoogleOAuthProvider>
- 사용자가 로그인에 성공하면, Google은 인증이 완료되었다는 증명으로 Authorization Code라는 임시 코드를 클라이언트(React 앱) 쪽으로 전달합니다.
- 이 코드는 매우 짧은 시간 동안만 유효하며, 직접 사용자 정보가 담겨있지 않습니다.
프론트엔드는 Authorization Code를 백엔드 서버에 전달
- 프론트엔드 앱은 받은 Authorization Code를 안전하게 백엔드 서버로 전송합니다.
- 이때 코드는 사용자가 직접 입력하는 정보가 아니고, 한 번만 쓸 수 있는 토큰 같은 역할입니다.
백엔드는 Google과 통신하여 Authorization Code로 Access Token과 ID Token을 획득
- 백엔드 서버는 Google의 인증 서버에 Authorization Code를 보내고,
Access Token과 ID Token을 받습니다. - Access Token은 Google API에 사용자 데이터를 요청할 때 쓰는 권한 증명 토큰이고,
- ID Token은 JWT 형태로 사용자의 인증 정보를 담고 있습니다.
백엔드는 Access Token 혹은 자체 발급한 세션 토큰을 프론트에 전달
- 백엔드는 받은 토큰 정보를 바탕으로 사용자 세션을 생성하거나,
자체 JWT 토큰을 발급해 프론트엔드에 전달할 수 있습니다. - 프론트엔드는 이 토큰을 가지고 로그인 상태를 유지하며,
필요할 때마다 백엔드에 인증 요청을 할 수 있습니다.
저는 Protected Route를 구현할 때, 로그인이 되어 있지 않은 사용자가 보호된 페이지에 접근하려 할 경우에 대비해 강제로 메인 페이지나 로그인 페이지로 이동하도록 설정했습니다.
이렇게 하면 인증되지 않은 사용자가 허가되지 않은 페이지에 접근하는 것을 막을 수 있고, 사용자 경험 측면에서도 로그인 페이지로 자연스럽게 안내할 수 있어 매우 효과적입니다.
즉, 로그인 상태를 검사한 후, 조건에 맞지 않으면 원하는 경로(메인 페이지 혹은 로그인 페이지)로 리다이렉트시키는 방식입니다.
// ProtectedRoute.js
import React from 'react';
import { Navigate } from 'react-router-dom';
import { useAuth } from './AuthContext';
const ProtectedRoute = ({ children }) => {
const { user } = useAuth();
if (!user) {
// 로그인 안된 경우 로그인 페이지로 이동
return <Navigate to="/login" replace />;
}
// 로그인 되어 있으면 접근 허용
return children;
};
export default ProtectedRoute;'웹' 카테고리의 다른 글
| 한글 입력 시 중복 요청 이슈와 해결 방법 (1) | 2025.04.15 |
|---|---|
| 이미지 파일 관리시 메모리 피크 제어 (2) | 2025.02.17 |
| Indexed DB 란??? [Chrome Extension을 개발하며] (0) | 2025.01.09 |
| Enum을 사용하면 안되는 이유 (0) | 2024.09.02 |
| Github Action build error 해결 (0) | 2024.07.24 |