이번 글에서는 Google Auth를 사용해 사용자 로그인 기능을 구현하고, 로그인 후 발급받은 AccessToken을 백엔드(FastAPI)에서 검증 및 사용자 인증의 흐름을 확인할 수 있습니다.
소셜 로그인을 적용하면 사용자는 별도의 회원가입 없이 Google 계정만으로 간편하게 로그인할 수 있습니다. 또한 NextAuth를 이용하면 보안성과 확장성을 모두 확보할 수 있습니다.
📚 목차
- 프로젝트 구조
- Google Cloud Console 설정
- NextAuth 설정하기
- FastAPI에서 사용자 등록 및 검증 API 구현
- JWT를 이용한 FastAPI 인증 검증
- 프론트엔드에서 FastAPI 호출하기
- 참고
📂 프로젝트 구조
PORTFOLIO-APP/
├── backend/
│ ├── models/
│ ├── routes/
│ │ └── user.py
│ ├── schemas/
│ ├── db.py
│ ├── main.py
│ ├── auth_utils.py
│ └── models.py
│
├── frontend/
│ ├── pages/
│ │ └── api/
│ │ └── auth/
│ │ └── [...nextauth].ts
│ ├── lib/
│ │ └── api.ts
│ ├── components/
│ ├── styles/
│ ├── .env.local
│ ├── package.json
│ └── tsconfig.json
│
├── docker-compose.yml
└── package-lock.json
☁️ Google Cloud Console 설정
Google OAuth 클라이언트를 등록해야 로그인 인증이 가능합니다.
1️⃣ OAuth 클라이언트 생성
- Google Cloud Console 접속
- API 및 서비스 → 사용자 인증 정보 → 사용자 인증 정보 만들기 → OAuth 클라이언트 ID
- OAuth 클라이언트 ID 생성
- 애플리케이션 유형: 웹 애플리케이션
- 승인된 리디렉션 URI:
http://localhost:3000/api/auth/callback/google

2️⃣ 환경 변수 설정
Next.js 루트 디렉토리에 .env.local 파일을 생성합니다.
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your_random_secret
💡
NEXTAUTH_SECRET는 JWT 서명용 키입니다.
터미널에서다음명령어로 생성할 수 있습니다.
python -c “import secrets; import base64; print(base64.b64encode(secrets.token_bytes(32)).decode())”
⚙️ NextAuth 설정하기
Next.js에서는 next-auth 패키지를 이용하면 간단하게 Google 로그인을 구현할 수 있습니다.
✅ 설치 명령어
npm install next-auth
✅ [...nextauth].ts 설정 예시
import NextAuth, { NextAuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID!;
const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET!;
const NEXTAUTH_SECRET = process.env.NEXTAUTH_SECRET!;
export const authOptions: NextAuthOptions = {
providers: [
GoogleProvider({
clientId: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
}),
],
secret: NEXTAUTH_SECRET,
callbacks: {
// ✅ JWT에 accessToken 저장
async jwt({ token, account }) {
if (account?.access_token) {
token.accessToken = account.access_token;
}
return token;
},
// ✅ session에 accessToken 포함
async session({ session, token }) {
(session as any).accessToken = (token as any).accessToken;
return session;
},
},
};
export default NextAuth(authOptions);
🔍 핵심 포인트
useSession()훅으로 로그인 상태를 쉽게 관리 가능jwt()콜백에서 구글에서 받은 access_token을 저장session()콜백에서 클라이언트가 접근 가능한 세션에 전달
🧩FastAPI에서 사용자 등록 및 검증 API 구현
이제 FastAPI에서 Google 로그인 사용자 정보를 저장 및 조회하는 로직을 구현합니다.
✅ user.py — 사용자 라우터 예시
from fastapi import APIRouter, Depends, HTTPException, Header, Body
from sqlmodel import Session, select
from db import get_session
from models import User
from auth_utils import verify_google_token # JWT 검증 로직
router = APIRouter()
# ✅ Google 로그인 후 사용자 검증
@router.post("/auth/google/check")
def check_google_user(
authorization: str = Header(...),
session: Session = Depends(get_session)
):
if not authorization.startswith("Bearer "):
raise HTTPException(status_code=401, detail="Invalid Authorization header")
token = authorization.replace("Bearer ", "")
google_data = verify_google_token(token)
email = google_data.get("email")
if not email:
raise HTTPException(status_code=401, detail="Invalid token: email not found")
user = session.exec(select(User).where(User.email == email)).first()
if user:
return {"exists": True, "user": {"id": user.id, "email": user.email, "nickname": user.nickname}}
📄 JWT를 이용한 FastAPI 인증 검증
Google 로그인으로 받은 AccessToken이 유효한지 확인하려면
Google의 tokeninfo API를 호출해 JWT를 검증합니다.
✅ auth_utils.py 예시
import requests
from fastapi import HTTPException
GOOGLE_TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo"
def verify_google_token(token: str):
response = requests.get(GOOGLE_TOKEN_INFO_URL, params={"access_token": token})
if response.status_code != 200:
raise HTTPException(status_code=401, detail="Invalid Google token")
return response.json()
이 함수는 Google의 인증 서버에 토큰을 전달하고,
유효하지 않으면 401 Unauthorized 예외를 발생시킵니다.
🎨 프론트엔드에서 FastAPI 호출하기
Next.js 프론트엔드에서는 next-auth의 session 객체에 담긴 accessToken을 이용해
FastAPI로 JWT 기반 인증 요청을 보낼 수 있습니다.
✅ FastAPI로 사용자 검증 요청 예시
// ✅ FastAPI로 사용자 확인 요청
const accessToken = (session as any)?.accessToken;
const userCheckRes = await callApi.post(
"/users/auth/google/check",
{},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);
if (userCheckRes.data.exists) {
console.log("✅ 기존 사용자 로그인:", userCheckRes.data.user);
} else {
console.log("🆕 신규 사용자 회원가입 완료:", userCheckRes.data.user);
}
🧩 전체 흐름 요약
| 단계 | 동작 내용 |
|---|---|
| ① | 사용자가 Google 로그인 버튼 클릭 |
| ② | next-auth가 Google OAuth 인증 처리 |
| ③ | 인증 성공 시, session.accessToken에 Google JWT 저장 |
| ④ | 프론트엔드가 FastAPI로 Authorization: Bearer <accessToken> 전송 |
| ⑤ | FastAPI가 verify_google_token()으로 JWT 유효성 검증 |
이로써 Next.js와 FastAPI가 분리된 환경에서도 완전한 Google 인증 연동이 가능합니다 ✅
🔒 보안 팁
.env파일은 반드시.gitignore에 포함시켜 커밋하지 않습니다.- 토큰 검증은 반드시 HTTPS 환경에서만 수행해야 합니다.
- AccessToken은 세션에만 일시적으로 저장하고, 장기 저장은 피해야 합니다.