sequenceDiagram
participant U as 사용자
participant F as 프론트엔드 (SvelteKit)
participant B as 백엔드 (Django)
participant P as OAuth Provider
U->>F: 소셜 로그인 버튼 클릭
F->>P: 인증 페이지로 리다이렉트
P->>U: 로그인 / 권한 동의
P->>F: Authorization Code 전달 (callback)
F->>B: POST /api/auth/{provider}/callback/ (code, redirect_uri)
B->>P: Authorization Code → Access Token 교환
P-->>B: Access Token 반환
B->>P: Access Token으로 사용자 정보 요청
P-->>B: 사용자 정보 반환
alt 기존 사용자
B-->>F: JWT 토큰 반환 (200)
else 신규 사용자
B-->>F: NICKNAME_REQUIRED + temp_key (200)
F->>U: 닉네임 입력 폼 표시
U->>F: 닉네임 입력
F->>B: POST /api/auth/{provider}/callback/ (temp_key, nickname)
B-->>F: JWT 토큰 반환 (201)
end
F->>F: localStorage에 토큰 저장
F->>U: 대시보드로 이동
OAuth2 소셜 로그인
Django REST Framework를 사용하여 Google, Naver, Kakao OAuth2 소셜 로그인을 구현하는 방법 중 각 OAuth2 프로바이더별 설정 방법을 정리했다. 사용자가 구글, 카카오, 네이버로 로그인 했을 때 닉네임을 Provider로부터 받아오되, 사용자가 직접 수정하여 백엔드로 전송해서 회원등록을 하는 시나리오를 바탕으로 작성했다.
개요
기술 스택
백엔드
- Django 6.0+ / Django REST Framework 3.16+
djangorestframework-simplejwt— JWT 토큰 발급social-auth-app-django— OAuth2 인증
프론트엔드
- SvelteKit
- localStorage 기반 토큰 저장
- iOS
인증 흐름
2단계(Two-Step) OAuth 흐름을 사용한다.
신규 사용자의 경우 OAuth 프로필을 캐시(TTL 10분)에 저장하고, 닉네임 입력 후 계정을 생성한다. 이미 가입된 사용자는 바로 JWT 토큰을 발급받는다.
사전 준비: OAuth 앱 등록
- Google Cloud Console에 접속한다.
- 프로젝트를 생성하거나 기존 프로젝트를 선택한다.
- API 및 서비스 > 사용자 인증 정보로 이동한다.
- OAuth 2.0 클라이언트 ID를 생성한다.
- 애플리케이션 유형: 웹 애플리케이션
- 승인된 리디렉션 URI:
- sveltekit:
http://localhost:5173/auth/google/callback(개발), 운영 도메인 추가 - iOS:
http://localhost:8000/api/auth/google/callback/
- sveltekit:
- Client ID와 Client Secret을 메모한다.
노트
OAuth 동의 화면에서 범위(scope)로 openid, email, profile을 설정해야 한다.
Kakao
- Kakao Developers에 접속한다.
- 애플리케이션 추가를 진행한다.
카카오 로그인 할 때 사용자의 이메일을 가져오기 위해서는 비즈앱으로 등록해야 한다. 비즈앱으로 등록하려면 앱 아이콘을 설정해야 한다.
앱 > 일반 > 앱 기본 정보 설정:
- 앱 아이콘 등록
- 앱 대표 도메인: 비워둔다.
- 카카오 회원 인증 또는 사업자 번호를 입력해서 비즈앱으로 등록한다
카카오 로그인 > 일반
- 사용 설정: On
- OpenID Connect: On
카카오 로그인 > 개인정보:
- 닉네임
- 프로필 사진
- 카카오 계정(이메일)
앱 > 플랫폼 키 > REST API 키:
- 카카오 로그인 리다이렉트 URI:
- http://localhost:5173/auth/kakao/callback
- http://localhost:8000/api/auth/kakao/callback/
- 클라이언트 시크릿:
- 카카오 로그인: On
- 비즈니스 인증: On
앱 > 플랫폼 키 > 네이티브 앱 키:
- iOS 앱 정보
- 번들 ID: iOS 프로젝트의 Xcode 설정에서
Bundle Identifier값
- 번들 ID: iOS 프로젝트의 Xcode 설정에서
백엔드 구현
환경 변수
.env.local
GOOGLE_CLIENT_ID=<your-google-client-id>
GOOGLE_CLIENT_SECRET=<your-google-client-secret>
NAVER_CLIENT_ID=<your-naver-client-id>
NAVER_CLIENT_SECRET=<your-naver-client-secret>
KAKAO_CLIENT_ID=<your-kakao-client-id>
KAKAO_CLIENT_SECRET=<your-kakao-client-secret>Provider별 엔드포인트
| Provider | Token URL | User Info URL |
|---|---|---|
https://oauth2.googleapis.com/token |
https://www.googleapis.com/oauth2/v2/userinfo |
|
| Naver | https://nid.naver.com/oauth2.0/token |
https://openapi.naver.com/v1/nid/me |
| Kakao | https://kauth.kakao.com/oauth/token |
https://kapi.kakao.com/v2/user/me |
중요
Naver는 CSRF 방지를 위해 state 파라미터가 필수이다. 프론트엔드에서 생성한 state 값을 콜백 시 검증해야 한다.
노트
Provider별 응답 형식 차이:
- Google: 최상위 레벨에
id,email,name포함 - Naver:
response키 아래에 사용자 정보 위치 - Kakao:
kakao_account.email,kakao_account.profile.nickname등 중첩 구조
프론트엔드 구현
OAuth 설정 파일
각 Provider별 Client ID와 Callback 경로를 설정한다.
src/lib/config/google.js
export const GOOGLE_CLIENT_ID = '<your-google-client-id>';
export const GOOGLE_CALLBACK_PATH = '/auth/google/callback';src/lib/config/naver.js
export const NAVER_CLIENT_ID = '<your-naver-client-id>';
export const NAVER_CALLBACK_PATH = '/auth/naver/callback';src/lib/config/kakao.js
export const KAKAO_CLIENT_ID = '<your-kakao-rest-api-key>';
export const KAKAO_CALLBACK_PATH = '/auth/kakao/callback';| Provider | 인증 URL | 특이 사항 |
|---|---|---|
accounts.google.com/o/oauth2/v2/auth |
scope에 openid email profile 필요 |
|
| Naver | nid.naver.com/oauth2.0/authorize |
state 파라미터 필수 (CSRF 방지) |
| Kakao | kauth.kakao.com/oauth/authorize |
REST API 키를 client_id로 사용 |
보안 고려사항
- CSRF 방지 (Naver):
crypto.randomUUID()로 state 토큰을 생성하고sessionStorage에 저장한 뒤, 콜백에서 검증한다. - Authorization Code는 서버 간 교환: Client Secret은 백엔드에서만 사용하며, 프론트엔드에 노출하지 않는다.
- 프로필 캐시 TTL: 신규 사용자의 OAuth 프로필은 10분 후 자동 만료된다.
- 이메일 충돌 감지: 동일 이메일이 다른 OAuth Provider로 이미 가입된 경우 에러를 반환한다.
- JWT 토큰 관리: Access Token 만료 시 Refresh Token으로 갱신하며, 401 응답 시 자동으로 재시도한다.
Provider별 비교
| 항목 | 값 |
|---|---|
| 인증 URL | accounts.google.com/o/oauth2/v2/auth |
| Token URL | oauth2.googleapis.com/token |
| User Info URL | googleapis.com/oauth2/v2/userinfo |
| Scope 설정 | openid email profile |
| CSRF (state) | 선택 |
| 응답 구조 | 플랫 |
| Client ID 유형 | OAuth 2.0 클라이언트 ID |
Kakao
| 항목 | 값 |
|---|---|
| 인증 URL | kauth.kakao.com/oauth/authorize |
| Token URL | kauth.kakao.com/oauth/token |
| User Info URL | kapi.kakao.com/v2/user/me |
| Scope 설정 | 개발자센터에서 설정 |
| CSRF (state) | 선택 |
| 응답 구조 | 중첩 (kakao_account) |
| Client ID 유형 | REST API 키 |