Feat: 소셜 로그인 추가 및 인증 페이지 UI 테마 정리

app/login/page.tsx
- Google/Kakao 소셜 로그인 버튼을 폼으로 연동하고 액션 호출 추가
- 로그인 페이지의 배경/버튼/텍스트 색상 등 UI 테마를 파스텔에서 그레이/다크톤으로 통일
- 소셜 버튼 마크업 및 스타일 정리

app/signup/page.tsx
- 회원가입 페이지 배경 및 버튼 색상을 그레이/다크톤으로 변경
- 아이콘 배경 그라디언트 및 링크 색상 업데이트

app/forgot-password/page.tsx
- 비밀번호 재설정 요청 페이지의 배경, 블러 효과 및 버튼 스타일을 그레이/다크톤으로 변경
- 아이콘 배경 및 링크 색상 업데이트

app/reset-password/page.tsx
- 비밀번호 재설정 페이지의 배경, 블러 효과 및 버튼 스타일을 그레이/다크톤으로 변경
- 아이콘 배경 업데이트

features/auth/actions.ts
- Google 및 Kakao OAuth 시작을 위한 공통 헬퍼(signInWithProvider) 추가
- signInWithGoogle 및 signInWithKakao 액션을 구현하여 OAuth 흐름을 시작하도록 추가
This commit is contained in:
2026-02-03 15:44:55 +09:00
parent 43119caf80
commit 151626b181
5 changed files with 175 additions and 73 deletions

View File

@@ -385,3 +385,94 @@ export async function updatePassword(formData: FormData) {
`/login?message=${encodeURIComponent(AUTH_ERROR_MESSAGES.PASSWORD_RESET_SUCCESS)}`,
);
}
// ========================================
// 소셜 로그인 (OAuth)
// ========================================
/**
* [OAuth 로그인 헬퍼 함수]
*
* Google, Kakao 등의 소셜 로그인 제공자를 통해 인증을 수행합니다.
*
* PKCE (Proof Key for Code Exchange) 플로우:
* 1. 이 함수가 signInWithOAuth를 호출하면 Supabase가 OAuth URL 반환
* 2. 사용자를 해당 OAuth 제공자(Google/Kakao) 로그인 페이지로 리다이렉트
* 3. 사용자가 로그인 및 권한 동의
* 4. OAuth 제공자가 /auth/callback?code=xxx로 리다이렉트
* 5. callback 라우트에서 code를 세션으로 교환 (exchangeCodeForSession)
* 6. 메인 페이지로 최종 리다이렉트
*
* 자동 회원가입:
* - 첫 로그인 시 auth.users 테이블에 자동으로 사용자 생성
* - 이메일, provider, metadata(프로필 사진, 이름 등) 저장
* - 기존 사용자는 그냥 로그인
*
* @param provider - OAuth 제공자 ('google' | 'kakao')
*/
async function signInWithProvider(provider: "google" | "kakao") {
const supabase = await createClient();
// 1. OAuth 인증 시작
const { data, error } = await supabase.auth.signInWithOAuth({
provider,
options: {
// PKCE 플로우를 위한 콜백 URL
// OAuth 제공자 인증 후 이 URL로 code와 함께 리다이렉트됨
redirectTo: `${process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3001"}/auth/callback`,
},
});
// 2. 에러 처리
if (error) {
console.error(`[${provider} OAuth] 로그인 실패:`, error.message);
return redirect(
`/login?message=${encodeURIComponent(`${provider} 로그인에 실패했습니다. 다시 시도해 주세요.`)}`,
);
}
// 3. OAuth 제공자 로그인 페이지로 리다이렉트
// data.url은 Google/Kakao의 인증 페이지 URL
if (data.url) {
redirect(data.url);
}
// 4. URL이 없는 경우 (예상치 못한 상황)
redirect(
`/login?message=${encodeURIComponent("로그인 처리 중 오류가 발생했습니다.")}`,
);
}
/**
* [Google 로그인 액션]
*
* Google 계정으로 로그인합니다.
* "Google로 로그인" 버튼에서 호출됩니다.
*
* 처리 과정:
* 1. signInWithOAuth 호출하여 Google OAuth URL 받기
* 2. Google 로그인 페이지로 리다이렉트
* 3. (사용자가 Google에서 로그인 및 권한 동의)
* 4. /auth/callback으로 돌아와서 세션 생성
* 5. 메인 페이지로 이동
*/
export async function signInWithGoogle() {
return signInWithProvider("google");
}
/**
* [Kakao 로그인 액션]
*
* Kakao 계정으로 로그인합니다.
* "Kakao로 로그인" 버튼에서 호출됩니다.
*
* 처리 과정:
* 1. signInWithOAuth 호출하여 Kakao OAuth URL 받기
* 2. Kakao 로그인 페이지로 리다이렉트
* 3. (사용자가 Kakao에서 로그인 및 권한 동의)
* 4. /auth/callback으로 돌아와서 세션 생성
* 5. 메인 페이지로 이동
*/
export async function signInWithKakao() {
return signInWithProvider("kakao");
}