OIDC 소셜로그인

OIDC 인증 프로토콜 흐름 문서
목차
OIDC 프로토콜 개요
프로젝트 구현 상세
카카오 로그인 흐름
애플 로그인 흐름
공통 OIDC 패턴
로그아웃 처리
보안 고려사항
OIDC 프로토콜 개요
OpenID Connect(OIDC)는 OAuth 2.0 프로토콜 위에 구축된 인증 레이어입니다.
OIDC는 클라이언트가 사용자의 신원을 확인하고 프로필 정보를 얻을 수 있게 해주는 표준화된 방법을 제공합니다.
주요 구성 요소
End-User: 인증을 요청하는 사용자
Relying Party (RP): OIDC 클라이언트, 사용자 인증을 요청하는 애플리케이션
OpenID Provider (OP): 사용자를 인증하고 클라이언트에 정보를 제공하는 서버 (예: 카카오, 애플)
ID Token: 사용자 인증 정보를 포함하는 JWT(JSON Web Token)
UserInfo Endpoint: 인증된 사용자에 대한 추가 정보를 제공하는 API
기본 인증 흐름 (Authorization Code Flow)
클라이언트(앱)가 사용자를 OpenID Provider(카카오, 애플 등)로 리디렉션합니다.
사용자가 OpenID Provider에서 인증합니다.
OpenID Provider가 인증 코드와 함께 사용자를 클라이언트의 리디렉션 URI로 돌려보냅니다.
클라이언트는 인증 코드를 사용하여 OpenID Provider의 토큰 엔드포인트에 ID 토큰과 액세스 토큰을 요청합니다.
클라이언트는 ID 토큰을 검증하고 필요한 경우 액세스 토큰을 사용하여 UserInfo 엔드포인트에서 추가 사용자 정보를 요청합니다.
프로젝트 구현 상세
oidc-client-ts라이브러리를 사용하여 OIDC 인증을 구현합니다.
카카오와 애플 로그인 모두 동일한 패턴을 따르지만 각 제공자별 설정이 다릅니다.
카카오 로그인 흐름
- OIDC 설정 (KakaoLogin.tsx)
const oidcConfig = { authority: 'https://kauth.kakao.com', client_id: '060234bee3c80ca83c81629cc92e5419', // 카카오 앱 키 redirect_uri: 'http://localhost:5173/oauth/callback', response_type: 'code', scope: 'openid profile_nickname profile_image account_email', loadUserInfo: true, userStore: new WebStorageStateStore({ store: window.localStorage }) }
- 로그인 시작 (KakaoLogin.tsx)
사용자가 카카오 로그인 버튼을 클릭하면loginWithOIDC함수가 호출됩니다:
const loginWithOIDC = async () => { try { await userManager.signinRedirect() } catch (error) { console.error('OIDC 로그인 시작 실패:', error) } }
이 함수는 사용자를 카카오 인증 페이지로 리디렉션합니다.
- 콜백 처리 (OAuth.tsx)
사용자가 카카오에서 인증을 완료하면 지정된 리디렉션 URI(/oauth/callback)로 돌아옵니다. OAuth.tsx 컴포넌트에서 이 콜백을 처리합니다:
const handleCallback = async () => { try { // OIDC 콜백 처리 const user = await userManager.signinRedirectCallback() // ID 토큰 추출 const id_token = user.id_token // 백엔드 API로 ID 토큰 전송 const response = await fetch('http://192.168.0.69:8080/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ provider: 'kakao', token: id_token }) }) // 서버에서 받은 JWT 토큰 저장 const data = await response.json() localStorage.setItem('access_token', data.access_token) // 홈으로 리디렉션 replace(ACTIVITIES.HOME, {}) } catch (error) { // 오류 처리 } }
애플 로그인 흐름
- OIDC 설정 (AppleLogin.tsx)
const oidcConfig = { authority: 'https://appleid.apple.com', client_id: 'com.your.app.id', // Apple 서비스 ID redirect_uri: 'http://localhost:5173/oauth/apple/callback', response_type: 'code id_token', scope: 'name email', loadUserInfo: true, userStore: new WebStorageStateStore({ store: window.localStorage }) }
애플 로그인은response_type이code id_token으로 설정되어 있어 인증 코드와 ID 토큰을 모두 직접 받습니다.
- 로그인 시작 (AppleLogin.tsx)
카카오 로그인과 동일한 패턴을 사용합니다:
const loginWithOIDC = async () => { try { await userManager.signinRedirect() } catch (error) { console.error('OIDC 로그인 시작 실패:', error) } }
- 콜백 처리 (OAuthApple.tsx)
애플 인증 후 콜백 처리도 카카오와 유사하지만, 제공자 이름이 'apple'로 설정됩니다:
// 백엔드 API로 ID 토큰 전송 const response = await fetch('http://192.168.0.69:8080/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ provider: 'apple', token: id_token }) })
공통 OIDC 패턴
두 로그인 구현 모두 다음과 같은 공통 패턴을 따릅니다:
OIDC 설정: 각 제공자에 맞는 설정으로UserManager인스턴스를 생성합니다.
로그인 시작:userManager.signinRedirect()를 호출하여 사용자를 인증 제공자로 리디렉션합니다.
콜백 처리:
userManager.signinRedirectCallback()을 호출하여 인증 코드를 처리하고 토큰을 받습니다.
ID 토큰을 백엔드 API로 전송합니다.
백엔드에서 받은 JWT 토큰을 localStorage에 저장합니다.
로그인 상태 확인:userManager.getUser()를 호출하여 현재 로그인 상태를 확인합니다.