From 5b2f8adc87799b7684466a32eda51b17190512b8 Mon Sep 17 00:00:00 2001 From: byeongcheolryu Date: Mon, 24 Nov 2025 18:57:35 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=9A=94=EC=B2=AD=20=EB=B0=A9=EC=A7=80=20=EB=B0=8F?= =?UTF-8?q?=20Strict=20Mode=20=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로그인 진행 중 상태 관리 추가 (isLoggingIn) - 중복 요청 차단 로직 구현 - 로그인 버튼 비활성화 및 로딩 표시 - next.config.ts reactStrictMode 활성화 🤖 Generated with Claude Code Co-Authored-By: Claude --- next.config.ts | 1 + src/components/auth/LoginPage.tsx | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/next.config.ts b/next.config.ts index b83282b2..4fa6e946 100644 --- a/next.config.ts +++ b/next.config.ts @@ -4,6 +4,7 @@ import createNextIntlPlugin from 'next-intl/plugin'; const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts'); const nextConfig: NextConfig = { + reactStrictMode: true, // 🧪 TEST: Strict Mode 비활성화로 중복 요청 테스트 turbopack: {}, // ✅ CRITICAL: Next.js 15 + next-intl compatibility typescript: { // ⚠️ WARNING: This allows production builds to complete even with TypeScript errors diff --git a/src/components/auth/LoginPage.tsx b/src/components/auth/LoginPage.tsx index 1384b618..18604814 100644 --- a/src/components/auth/LoginPage.tsx +++ b/src/components/auth/LoginPage.tsx @@ -28,6 +28,7 @@ export function LoginPage() { const [rememberMe, setRememberMe] = useState(false); const [error, setError] = useState(""); const [isChecking, setIsChecking] = useState(true); + const [isLoggingIn, setIsLoggingIn] = useState(false); // ✅ 로그인 진행 중 상태 // 이미 로그인된 상태인지 확인 (페이지 로드 시, 뒤로가기 시) useEffect(() => { @@ -53,6 +54,12 @@ export function LoginPage() { }, [router]); const handleLogin = async () => { + // ✅ 중복 요청 방지 + if (isLoggingIn) { + console.warn('⚠️ 로그인 진행 중 - 중복 요청 차단'); + return; + } + setError(""); // Validation @@ -61,6 +68,8 @@ export function LoginPage() { return; } + setIsLoggingIn(true); // ✅ 로그인 시작 + try { // 🔵 Next.js 프록시 → PHP /api/v1/login (토큰을 HttpOnly 쿠키로 저장) const response = await fetch('/api/auth/login', { @@ -122,6 +131,8 @@ export function LoginPage() { } else { setError(error.message || t('invalidCredentials')); } + } finally { + setIsLoggingIn(false); // ✅ 로그인 종료 (성공/실패 상관없이) } }; @@ -249,10 +260,20 @@ export function LoginPage() {