📘 [Aura_AI] [2편] App Router 환경에서 OAuth 인증 설계하기
— Google OAuth + Auth.js(v5)를 선택한 이유
안녕하세요.
Aura_AI 프로젝트 두 번째 기록입니다.
이번 글에서는
Next.js App Router 환경에서 Google OAuth 인증을 어떻게 설계했는지,
그리고 단순 구현을 넘어 왜 이 구조를 선택했는지를 중심으로 정리합니다.
이번 단계의 목표는 단순했습니다.
“로그인이 되는 것”이 아니라
App Router 환경에서 확장 가능한 인증 구조를 만드는 것
🎯 Day 7 목표
- Google 로그인 버튼 클릭 → OAuth 인증 성공
- 인증 후 유저 정보를 세션에 안전하게 저장
- App Router 환경에서 Hydration 오류 없이 안정적으로 동작
- 로그인 성공 시 /chat 페이지로 리다이렉트
✅ 결과 요약
- Google OAuth 로그인 성공
- 로그인 후 /chat 정상 이동
- session.user.id 접근 가능
- Day 8(Zustand, middleware)로 바로 확장 가능한 상태 완성
1. 왜 OAuth 인증을 먼저 설계했을까?
Aura_AI는 개인화된 추천 서비스입니다.
즉, 유저의 상태를 기준으로 서비스 흐름이 달라집니다.
- 로그인 여부
- 유저 식별자(id)
- 이후 저장될 취향 / 위치 / 기록
이런 서비스에서 인증은 “부가 기능”이 아니라
모든 기능의 출발점입니다.
그래서 UI보다 먼저
인증 흐름과 세션 구조부터 설계하는 것을 Day 7의 목표로 잡았습니다.
2. 왜 Google OAuth인가?
처음부터 ID/PW 회원가입을 만들 수도 있었지만,
Day 7에서는 OAuth를 우선 선택했습니다.
이유는 명확합니다.
- 실제 서비스에서 가장 많이 쓰이는 인증 방식
- 비밀번호 관리 부담 없음
- 빠른 온보딩 → 서비스 진입 장벽 최소화
- 이후 자체 회원가입과 병행 설계 가능
👉 즉, OAuth는 “편의성”이 아니라
서비스 초기 진입 전략입니다.
3. App Router 환경에서 Auth.js(v5)를 선택한 이유
npm install next-auth@beta
Next.js App Router 환경에서는
**Auth.js v5(beta)**가 사실상 정석에 가깝습니다.
v5를 선택한 이유
- App Router 구조와 자연스럽게 맞음
- handlers(GET / POST) 기반 API 설계
- 인증 로직을 auth.ts 한 파일로 집중 관리
- 이후 DB Adapter, middleware 확장이 쉬움
👉 “지금은 OAuth지만,
나중에 인증 서버로 확장 가능한 구조”를 만들기 위함입니다.
4. auth.ts는 ‘설정 파일’이 아니다
Day 7에서 가장 중요했던 파일은 auth.ts입니다.
이 파일은 단순한 Google 로그인 설정 파일이 아니라
인증 상태 흐름(JWT → Session)을 설계한 핵심 파일입니다.
auth.ts가 담당하는 역할
- Google OAuth Provider 설정
- JWT 생성 및 관리
- 클라이언트 Session 구조 정의
- /api/auth/* 요청의 실제 처리 로직
// /auth.ts
import NextAuth from "next-auth";
import Google from "next-auth/providers/google";
export const {
handlers: { GET, POST },
auth,
signIn,
signOut,
} = NextAuth({
providers: [
Google({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}),
],
callbacks: {
async jwt({ token, user }) {
if (user) token.id = user.id;
return token;
},
async session({ session, token }) {
if (session.user) {
session.user.id = token.id as string;
}
return session;
},
},
});
5. 왜 JWT → Session 구조로 설계했을까?
❌ 단순한 방식
session.user.id = user.id;
- 로그인 직후엔 동작
- 새로고침 / SSR 이후 user 없음 → ❌
✅ 현재 구조 (정석)
user (로그인 시)
→ jwt (서버 인증 상태)
→ session (클라이언트 전달)
이 구조의 장점
- 새로고침에도 인증 정보 유지
- SSR / CSR 환경 모두 안정적
- middleware, Zustand와 자연스럽게 연결 가능
👉 **서버 기준 인증 상태(JWT)**와
**클라이언트 사용 세션(Session)**을 명확히 분리한 설계입니다.
6. App Router에서 Auth API를 연결하는 방식
App Router에서는
HTTP 메서드 기반으로 API를 정의합니다.
// app/api/auth/[...nextauth]/route.ts
export { GET, POST } from "@/auth";
이 파일은 로직을 구현하지 않습니다.
의미는 단 하나입니다.
“auth.ts에서 이미 만들어진
GET / POST 인증 핸들러를
이 경로에 그대로 연결한다.”
이 구조 덕분에:
- 인증 로직은 auth.ts에 집중
- API Route는 얇고 단순
- 재사용성과 확장성이 좋아집니다
7. Providers를 분리한 이유 (Hydration 오류 해결)
App Router에서
layout.tsx는 서버 컴포넌트로 유지하는 것이 핵심입니다.
그래서 클라이언트 전용 상태(Session, Theme)는
별도의 providers.tsx로 분리했습니다.
// app/providers.tsx
"use client";
import { SessionProvider } from "next-auth/react";
import { ThemeProvider } from "next-themes";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<SessionProvider>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</SessionProvider>
);
}
// app/layout.tsx
<html lang="ko" suppressHydrationWarning>
<body>
<Providers>{children}</Providers>
</body>
</html>
이렇게 나눈 이유
- Server / Client 경계 명확화
- App Router 철학 유지
- Theme 변경으로 인한 hydration 오류 방지
- Provider 확장에 유리한 구조
8. Day 7에서 실제로 겪은 문제들
- 환경 변수 이름 불일치 → OAuth 실패
- AUTH_SECRET에 명령어 문자열 그대로 입력 → 인증 오류
- Theme class mismatch → hydration warning
- button 중첩 → 서버/클라이언트 DOM 불일치
👉 이 문제들을 해결하며
“왜 이런 구조가 정석인지”를 몸으로 이해할 수 있었습니다.
마치며
Day 7은
“로그인 기능을 붙인 날”이 아니라,
App Router 환경에서 인증을 어떻게 설계해야 하는지
기준을 세운 날이었습니다.
이 구조를 기반으로
다음 단계에서는:
- Zustand 전역 상태 관리
- OAuth 유저 / 일반 유저 통합
- 인증 기반 라우트 보호(middleware)
로 자연스럽게 확장할 예정입니다.
🔜 다음 편 예고
📘 [Aura_AI] [3편] OAuth vs 자체 회원가입 — 서비스에 맞는 인증 전략
'코디챗봇 프로젝트' 카테고리의 다른 글
| [Aura_Ai] [6편] 프로젝트 배포 (0) | 2026.02.13 |
|---|---|
| [Aura_Ai] [5편] 데이터 가공으로 UX 개선하기 (0) | 2026.02.02 |
| [Aura_Ai] [4편] GPT API를 활용한 서비스 설계 (0) | 2026.02.01 |
| [Aura_AI] [3편] OAuth만으로는 부족해서 자체 회원가입을 추가한 이유 (0) | 2026.01.23 |
| [Aura_AI] [1편] 화면만 그리던 프론트엔드 개발자가 ‘20단계 몰입 프로젝트’를 시작한 이유 (1) | 2026.01.11 |