diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 28c4403..6426970 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -1,2 +1,4 @@ -export { AuthProvider, useAuth } from '@/contexts/auth'; +import { AuthProvider, useAuth } from '@/contexts/auth'; + +export { AuthProvider, useAuth }; diff --git a/src/contexts/auth/signIn.ts b/src/contexts/auth/signIn.ts index a5a33af..bcc54a3 100644 --- a/src/contexts/auth/signIn.ts +++ b/src/contexts/auth/signIn.ts @@ -23,30 +23,26 @@ export const signIn = async (email: string, password: string) => { console.log('로그인 시도 중:', email); - // Supabase 기본 인증 시도 + // 직접 API 호출 방식 시도 try { - const { data, error } = await supabase.auth.signInWithPassword({ - email, - password - }); + return await signInWithDirectApi(email, password); + } catch (directApiError: any) { + console.error('직접 API 호출 방식 실패:', directApiError); - if (!error && data.user) { - showAuthToast('로그인 성공', '환영합니다!'); - return { error: null, user: data.user }; - } else if (error) { - console.error('로그인 오류:', error.message); + // 기본 Supabase 인증 방식 시도 + try { + const { data, error } = await supabase.auth.signInWithPassword({ + email, + password + }); - // REST API 오류인 경우 직접 API 호출 시도 - if (error.message.includes('json') || - error.message.includes('Unexpected end') || - error.message.includes('404') || - error.message.includes('Not Found')) { - console.warn('기본 로그인 실패, 직접 API 호출 시도:', error.message); - return await signInWithDirectApi(email, password); - } else { - // 다른 종류의 오류는 그대로 반환 - let errorMessage = error.message; + if (!error && data.user) { + showAuthToast('로그인 성공', '환영합니다!'); + return { error: null, user: data.user }; + } else if (error) { + console.error('Supabase 기본 로그인 오류:', error.message); + let errorMessage = error.message; if (error.message.includes('Invalid login credentials')) { errorMessage = '이메일 또는 비밀번호가 올바르지 않습니다.'; } else if (error.message.includes('Email not confirmed')) { @@ -56,24 +52,17 @@ export const signIn = async (email: string, password: string) => { showAuthToast('로그인 실패', errorMessage, 'destructive'); return { error: { message: errorMessage }, user: null }; } + } catch (basicAuthError: any) { + console.warn('Supabase 기본 인증 방식 예외 발생:', basicAuthError); + + // 오류 전파 + throw directApiError; } - } catch (basicAuthError: any) { - console.warn('기본 인증 방식 예외 발생:', basicAuthError); - - // 404 에러나 경로 오류인 경우에도 직접 API 호출 시도 - if (basicAuthError.message && ( - basicAuthError.message.includes('404') || - basicAuthError.message.includes('Not Found') - )) { - return await signInWithDirectApi(email, password); - } - - // 기본 로그인 실패 시 아래 직접 API 호출 방식 계속 진행 - return await signInWithDirectApi(email, password); } - // 기본 방식이 성공적으로 완료되지 않았을 경우 직접 API 호출 - return await signInWithDirectApi(email, password); + // 여기까지 왔다면 모든 로그인 시도가 실패한 것 + showAuthToast('로그인 실패', '로그인 처리 중 오류가 발생했습니다.', 'destructive'); + return { error: { message: '로그인 처리 중 오류가 발생했습니다.' }, user: null }; } catch (error: any) { console.error('로그인 중 예외 발생:', error); diff --git a/src/contexts/auth/signInUtils.ts b/src/contexts/auth/signInUtils.ts index 130f4a3..e8f7b1b 100644 --- a/src/contexts/auth/signInUtils.ts +++ b/src/contexts/auth/signInUtils.ts @@ -9,19 +9,19 @@ export const signInWithDirectApi = async (email: string, password: string) => { console.log('직접 API 호출로 로그인 시도'); try { - // 로그인 API 엔드포인트 URL 준비 - const supabaseUrl = localStorage.getItem('supabase_url') || 'http://a11.ism.kr'; + // API 호출 URL 및 헤더 설정 + const supabaseUrl = localStorage.getItem('supabase_url') || 'https://a11.ism.kr'; const supabaseKey = localStorage.getItem('supabase_key') || supabase.supabaseKey; // URL에 auth/v1이 이미 포함되어있는지 확인 const baseUrl = supabaseUrl.includes('/auth/v1') ? supabaseUrl : `${supabaseUrl}/auth/v1`; - // 토큰 엔드포인트 경로 + // 토큰 엔드포인트 경로 (curl 테스트와 동일한 형식으로) const tokenUrl = `${baseUrl}/token?grant_type=password`; console.log('로그인 API 요청 URL:', tokenUrl); - // 로그인 요청 보내기 + // 로그인 요청 보내기 (curl 테스트와 동일한 형식으로) const response = await fetch(tokenUrl, { method: 'POST', headers: { @@ -36,6 +36,7 @@ export const signInWithDirectApi = async (email: string, password: string) => { // HTTP 상태 코드 확인 if (response.status === 401) { + console.log('로그인 실패: 인증 오류'); showAuthToast('로그인 실패', '이메일 또는 비밀번호가 올바르지 않습니다.', 'destructive'); return { error: { message: '인증 실패: 이메일 또는 비밀번호가 올바르지 않습니다.' }, @@ -98,24 +99,20 @@ export const signInWithDirectApi = async (email: string, password: string) => { } // 응답 처리 - const responseData = await parseResponse(response); + const responseText = await response.text(); + console.log('로그인 응답 내용:', responseText); - // 빈 응답이나 파싱 실패 시 - if (responseData.status && !responseData.success && !responseData.error) { + let responseData; + try { + // 응답이 비어있지 않은 경우에만 JSON 파싱 시도 + responseData = responseText ? JSON.parse(responseText) : {}; + } catch (e) { + console.warn('JSON 파싱 실패:', e, '원본 응답:', responseText); if (response.status >= 200 && response.status < 300) { - // 성공 상태 코드이지만 응답 내용 없음 - showAuthToast('로그인 상태 확인 필요', '서버가 성공 응답을 보냈지만 내용이 없습니다. 세션 상태를 확인하세요.'); - - // 사용자 세션 확인 시도 - try { - const { data: userData } = await supabase.auth.getUser(); - if (userData.user) { - showAuthToast('로그인 성공', '환영합니다!'); - return { error: null, user: userData.user }; - } - } catch (sessionCheckError) { - console.error('세션 확인 오류:', sessionCheckError); - } + // 성공 응답이지만 JSON이 아닌 경우 (빈 응답 등) + responseData = { success: true }; + } else { + responseData = { error: '서버 응답을 처리할 수 없습니다' }; } } @@ -148,6 +145,24 @@ export const signInWithDirectApi = async (email: string, password: string) => { showAuthToast('로그인 후처리 오류', '로그인에 성공했지만 세션 설정에 실패했습니다.', 'destructive'); return { error: { message: '세션 설정 오류' }, user: null }; } + } else if (response.ok) { + // 응답 내용 없이 성공 상태인 경우 + try { + // 사용자 세션 확인 시도 + const { data: userData } = await supabase.auth.getUser(); + if (userData.user) { + showAuthToast('로그인 성공', '환영합니다!'); + return { error: null, user: userData.user }; + } else { + // 세션은 있지만 사용자 정보가 없는 경우 + showAuthToast('로그인 부분 성공', '로그인은 성공했지만 사용자 정보를 가져오지 못했습니다.', 'default'); + return { error: { message: '사용자 정보 조회 실패' }, user: null }; + } + } catch (userError) { + console.error('사용자 정보 조회 오류:', userError); + showAuthToast('로그인 후처리 오류', '로그인은 성공했지만 사용자 정보를 가져오지 못했습니다.', 'destructive'); + return { error: { message: '사용자 정보 조회 실패' }, user: null }; + } } else { // 오류 응답이나 예상치 못한 응답 형식 처리 console.error('로그인 오류 응답:', responseData); diff --git a/src/contexts/auth/signUpUtils.ts b/src/contexts/auth/signUpUtils.ts index 485bda6..59f4e31 100644 --- a/src/contexts/auth/signUpUtils.ts +++ b/src/contexts/auth/signUpUtils.ts @@ -9,7 +9,7 @@ export const signUpWithDirectApi = async (email: string, password: string, usern try { console.log('직접 API 호출로 회원가입 시도 중'); - const supabaseUrl = localStorage.getItem('supabase_url') || 'http://a11.ism.kr'; + const supabaseUrl = localStorage.getItem('supabase_url') || 'https://a11.ism.kr'; const supabaseKey = localStorage.getItem('supabase_key') || supabase.supabaseKey; // URL에 auth/v1이 이미 포함되어있는지 확인 @@ -46,8 +46,23 @@ export const signUpWithDirectApi = async (email: string, password: string, usern }; } - // 응답 처리 - const responseData = await parseResponse(response); + // 응답 내용 가져오기 + const responseText = await response.text(); + console.log('회원가입 응답 내용:', responseText); + + let responseData; + try { + // 응답이 비어있지 않은 경우에만 JSON 파싱 시도 + responseData = responseText ? JSON.parse(responseText) : {}; + } catch (e) { + console.warn('JSON 파싱 실패:', e, '원본 응답:', responseText); + if (response.status >= 200 && response.status < 300) { + // 성공 응답이지만 JSON이 아닌 경우 (빈 응답 등) + responseData = { success: true }; + } else { + responseData = { error: '서버 응답을 처리할 수 없습니다' }; + } + } if (responseData && responseData.error) { const errorMessage = responseData.error_description || responseData.error || '회원가입 실패'; @@ -93,6 +108,14 @@ export const signUpWithDirectApi = async (email: string, password: string, usern return { error: null, user }; } + } else if (response.ok) { + // 응답이 성공이지만 사용자 정보가 없는 경우 + showAuthToast('회원가입 성공', '계정이 생성되었습니다. 로그인해주세요.', 'default'); + return { + error: null, + user: { email }, + message: '회원가입 처리 완료' + }; } else { // 예상치 못한 응답 형식 const errorMessage = '회원가입 처리 중 오류가 발생했습니다. 나중에 다시 시도하세요.'; diff --git a/src/lib/supabase/config.ts b/src/lib/supabase/config.ts index ad5a870..60f97d5 100644 --- a/src/lib/supabase/config.ts +++ b/src/lib/supabase/config.ts @@ -1,3 +1,4 @@ + // 온프레미스 Supabase URL과 anon key 설정 export const getSupabaseUrl = () => { // 로컬 스토리지에서 설정된 URL을 우선 사용 @@ -50,7 +51,7 @@ export const getSupabaseUrl = () => { } // 기본값 사용 (환경 변수 대신) - return 'http://a11.ism.kr'; + return 'https://a11.ism.kr'; }; export const getSupabaseKey = () => { @@ -111,5 +112,5 @@ export const configureSupabase = (url: string, key: string, useProxy: boolean = // 원본 URL 반환 (프록시 없는 URL) export const getOriginalSupabaseUrl = () => { const storedUrl = localStorage.getItem('supabase_url'); - return storedUrl || process.env.SUPABASE_URL || 'http://a11.ism.kr:8000'; + return storedUrl || 'https://a11.ism.kr'; };