diff --git a/src/contexts/auth/authActions.ts b/src/contexts/auth/authActions.ts index 332e8cf..1364832 100644 --- a/src/contexts/auth/authActions.ts +++ b/src/contexts/auth/authActions.ts @@ -1,4 +1,3 @@ - import { supabase } from '@/lib/supabase'; import { toast } from '@/hooks/useToast.wrapper'; @@ -10,14 +9,11 @@ export const signIn = async (email: string, password: string) => { if (error) { console.error('로그인 오류:', error); - toast({ - title: '로그인 실패', - description: error.message, - variant: 'destructive', - }); return { error }; } + console.log('로그인 성공:', data); + toast({ title: '로그인 성공', description: '환영합니다!', @@ -32,11 +28,6 @@ export const signIn = async (email: string, password: string) => { ? '서버 연결에 실패했습니다. 네트워크 연결을 확인해주세요.' : '예상치 못한 오류가 발생했습니다.'; - toast({ - title: '로그인 오류', - description: errorMessage, - variant: 'destructive', - }); return { error }; } }; diff --git a/src/lib/supabase.ts b/src/lib/supabase.ts index f97ef3d..9e46008 100644 --- a/src/lib/supabase.ts +++ b/src/lib/supabase.ts @@ -41,6 +41,19 @@ try { // 온프레미스 설치를 위한 추가 설정 flowType: 'implicit', }, + global: { + fetch: (...args) => { + // CORS 디버깅을 위한 사용자 정의 fetch + console.log('Supabase fetch 요청:', args[0]); + return fetch(...args).then(response => { + console.log('Supabase 응답 상태:', response.status); + return response; + }).catch(err => { + console.error('Supabase fetch 오류:', err); + throw err; + }); + } + } }); // CORS 문제 확인을 위한 기본 헤더 테스트 @@ -59,7 +72,14 @@ try { if (response.ok) { console.log('Supabase REST API 연결 성공:', response.status); } else { - console.warn('Supabase REST API 연결 실패:', response.status); + console.warn('Supabase REST API 연결 실패:', response.status, response.statusText); + // 응답 세부 정보 로깅 + try { + const errorText = await response.text(); + console.warn('Supabase REST API 오류 응답:', errorText); + } catch (e) { + console.error('응답 내용 읽기 실패:', e); + } } } catch (err) { console.error('Supabase 서버 상태 확인 중 오류 (CORS 문제 가능성):', err); @@ -175,6 +195,7 @@ export const testSupabaseConnection = async () => { try { // 1. REST API 접근 테스트 try { + console.log('REST API 테스트 시작...'); const response = await fetch(`${supabaseUrl}/rest/v1/`, { method: 'GET', headers: { @@ -185,25 +206,36 @@ export const testSupabaseConnection = async () => { results.restApi = response.ok; if (!response.ok) { - results.errors.push(`REST API 오류: ${response.status} ${response.statusText}`); + const errorBody = await response.text(); + results.errors.push(`REST API 오류(${response.status} ${response.statusText}): ${errorBody || '응답 없음'}`); + console.error('REST API 테스트 실패:', response.status, errorBody); + } else { + console.log('REST API 테스트 성공'); } } catch (err: any) { - results.errors.push(`REST API 예외: ${err.message}`); + results.errors.push(`REST API 예외: ${err.message || '알 수 없는 오류'}`); + console.error('REST API 테스트 중 예외:', err); } // 2. 인증 서비스 테스트 try { + console.log('인증 서비스 테스트 시작...'); const { data, error } = await supabaseClient.auth.getSession(); results.auth = !error; if (error) { results.errors.push(`인증 오류: ${error.message}`); + console.error('인증 테스트 실패:', error); + } else { + console.log('인증 테스트 성공'); } } catch (err: any) { - results.errors.push(`인증 예외: ${err.message}`); + results.errors.push(`인증 예외: ${err.message || '알 수 없는 오류'}`); + console.error('인증 테스트 중 예외:', err); } // 3. 데이터베이스 연결 테스트 try { + console.log('데이터베이스 연결 테스트 시작...'); const { data, error } = await supabaseClient .from('transactions') .select('*') @@ -212,12 +244,22 @@ export const testSupabaseConnection = async () => { results.database = !error; if (error) { results.errors.push(`데이터베이스 오류: ${error.message}`); + console.error('데이터베이스 테스트 실패:', error); + } else { + console.log('데이터베이스 테스트 성공', data); } } catch (err: any) { - results.errors.push(`데이터베이스 예외: ${err.message}`); + results.errors.push(`데이터베이스 예외: ${err.message || '알 수 없는 오류'}`); + console.error('데이터베이스 테스트 중 예외:', err); + } + + // 오류가 없는 경우 메시지 추가 + if (results.errors.length === 0) { + results.errors.push('모든 테스트 통과! 연결 상태가 정상입니다.'); } } catch (err: any) { - results.errors.push(`테스트 실행 예외: ${err.message}`); + results.errors.push(`테스트 실행 예외: ${err.message || '알 수 없는 오류'}`); + console.error('전체 테스트 실행 중 예외:', err); } console.log('Supabase 연결 테스트 결과:', results); diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index a322b3c..e485639 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -16,6 +16,7 @@ const Login = () => { const [isLoading, setIsLoading] = useState(false); const [testLoading, setTestLoading] = useState(false); const [testResults, setTestResults] = useState(null); + const [loginError, setLoginError] = useState(null); const { toast } = useToast(); const navigate = useNavigate(); const { signIn, user } = useAuth(); @@ -29,6 +30,7 @@ const Login = () => { const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); + setLoginError(null); if (!email || !password) { toast({ @@ -44,9 +46,41 @@ const Login = () => { try { const { error } = await signIn(email, password); - if (!error) { + if (error) { + console.error("로그인 실패:", error); + let errorMessage = "로그인에 실패했습니다."; + + // Supabase 오류 메시지 처리 + if (error.message) { + if (error.message.includes("Invalid login credentials")) { + errorMessage = "이메일 또는 비밀번호가 올바르지 않습니다."; + } else if (error.message.includes("Email not confirmed")) { + errorMessage = "이메일 인증이 완료되지 않았습니다. 이메일을 확인해주세요."; + } else { + errorMessage = `오류: ${error.message}`; + } + } + + setLoginError(errorMessage); + + toast({ + title: "로그인 실패", + description: errorMessage, + variant: "destructive" + }); + } else { navigate("/"); } + } catch (err: any) { + console.error("로그인 과정에서 예외 발생:", err); + const errorMessage = err.message || "알 수 없는 오류가 발생했습니다."; + setLoginError(errorMessage); + + toast({ + title: "로그인 오류", + description: errorMessage, + variant: "destructive" + }); } finally { setIsLoading(false); } @@ -55,6 +89,7 @@ const Login = () => { // Supabase 연결 테스트 const runConnectionTest = async () => { setTestLoading(true); + setLoginError(null); try { const results = await testSupabaseConnection(); setTestResults(results); @@ -71,8 +106,10 @@ const Login = () => { variant: "destructive" }); } - } catch (error) { + } catch (error: any) { console.error("연결 테스트 중 오류:", error); + setLoginError(error.message || "테스트 실행 중 예상치 못한 오류가 발생했습니다."); + toast({ title: "연결 테스트 오류", description: "테스트 실행 중 예상치 못한 오류가 발생했습니다.", @@ -112,6 +149,12 @@ const Login = () => { + {loginError && ( +
+

{loginError}

+
+ )} +
비밀번호를 잊으셨나요? @@ -169,11 +212,43 @@ const Login = () => {
{testResults && testResults.errors.length > 0 && ( -
- {testResults.errors[0]} +
+ {testResults.errors.map((error: string, index: number) => ( +
{error}
+ ))}
)}
+ + {/* 고급 진단 정보 */} +
+ 고급 진단 정보 +
+
+

Supabase URL:

+

{testResults?.url || '알 수 없음'}

+
+
+

클라이언트 초기화:

+

{testResults?.client ? '성공' : '실패'}

+
+
+

브라우저 정보:

+

{navigator.userAgent}

+
+
+

앱 버전:

+

1.0.0

+
+ {testResults && ( +
+

REST API: {testResults.restApi ? '✅' : '❌'}

+

인증: {testResults.auth ? '✅' : '❌'}

+

데이터베이스: {testResults.database ? '✅' : '❌'}

+
+ )} +
+
; };