feat: 소셜 로그인(Google/Kakao) 및 회원가입 이메일 인증 추가
- User 엔티티 확장: passwordHash nullable, provider, emailVerified, 인증 토큰 해시/만료(select:false) - 회원가입: 자동 로그인 폐지 → 미인증 계정 생성 + 인증 메일 발송(MailService 플레이스홀더, 백엔드 로그로 링크 출력) - 이메일 인증: GET /auth/verify-email(해시 매칭+만료 검사) → 프론트로 리다이렉트, 재발송 엔드포인트 - 로그인 게이트: 미인증 로컬 403 차단, 소셜 전용 계정은 소셜 로그인 안내 - 소셜 OAuth: passport google/kakao 전략(키 미설정 시 자동 비활성), 이메일로 계정 매칭/생성 - 기존 로컬 계정 그랜드페더링(부팅 시 인증 완료 보정) - 프론트: 가입 후 인증 메일 안내 화면, 로그인 소셜 버튼 실연동 + 인증 결과 배너 - env(APP_API_URL/FRONTEND_URL/GOOGLE_*/KAKAO_*) 문서화, 문서·계약 갱신 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,23 @@
|
||||
import { useApi } from './useApi'
|
||||
import type { AuthUser, LoginPayload, SignupPayload } from '@/types/auth'
|
||||
import type {
|
||||
AuthUser,
|
||||
LoginPayload,
|
||||
SignupPayload,
|
||||
SignupResult,
|
||||
} from '@/types/auth'
|
||||
|
||||
// 인증 도메인 API Composable — 인터셉터가 success/data 를 언래핑하므로 data 타입으로 캐스팅
|
||||
export function useAuth() {
|
||||
const api = useApi()
|
||||
|
||||
// 회원가입 (성공 시 백엔드가 인증 쿠키를 설정해 자동 로그인됨)
|
||||
async function signup(payload: SignupPayload): Promise<AuthUser> {
|
||||
return (await api.post('/auth/signup', payload)) as unknown as AuthUser
|
||||
// 회원가입 — 인증 메일 발송 후 대기(자동 로그인 X). 인증 완료 전까지 로그인 불가.
|
||||
async function signup(payload: SignupPayload): Promise<SignupResult> {
|
||||
return (await api.post('/auth/signup', payload)) as unknown as SignupResult
|
||||
}
|
||||
|
||||
// 인증 메일 재발송
|
||||
async function resendVerification(email: string): Promise<void> {
|
||||
await api.post('/auth/resend-verification', { email })
|
||||
}
|
||||
|
||||
// 로그인
|
||||
@@ -26,5 +36,5 @@ export function useAuth() {
|
||||
return (await api.get('/auth/me', { silent: true })) as unknown as AuthUser
|
||||
}
|
||||
|
||||
return { signup, login, logout, fetchMe }
|
||||
return { signup, resendVerification, login, logout, fetchMe }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user