Refactor auth utils for Cloud
Simplify signUpUtils.ts and signInUtils.ts by removing unnecessary code related to CORS proxies, optimizing for Supabase Cloud environment.
This commit is contained in:
@@ -1,208 +1,53 @@
|
||||
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import { parseResponse, showAuthToast, handleNetworkError } from '@/utils/auth';
|
||||
import { getProxyType, isCorsProxyEnabled, getSupabaseUrl, getOriginalSupabaseUrl } from '@/lib/supabase/config';
|
||||
import { showAuthToast } from '@/utils/auth';
|
||||
|
||||
/**
|
||||
* 직접 API 호출을 통한 로그인 시도 (대체 방법)
|
||||
* 로그인 기능 - Supabase Cloud 환경에 최적화
|
||||
*/
|
||||
export const signInWithDirectApi = async (email: string, password: string) => {
|
||||
console.log('직접 API 호출로 로그인 시도');
|
||||
console.log('Supabase Cloud 로그인 시도');
|
||||
|
||||
try {
|
||||
// API 호출 URL 및 헤더 설정
|
||||
const supabaseUrl = getOriginalSupabaseUrl(); // 원본 URL 사용
|
||||
const proxyUrl = getSupabaseUrl(); // 프록시 적용된 URL
|
||||
const supabaseKey = localStorage.getItem('supabase_key') || supabase.supabaseKey;
|
||||
|
||||
// 프록시 정보 로그
|
||||
const usingProxy = isCorsProxyEnabled();
|
||||
const proxyType = getProxyType();
|
||||
console.log(`CORS 프록시 사용: ${usingProxy ? '예' : '아니오'}, 타입: ${proxyType}, 프록시 URL: ${proxyUrl}`);
|
||||
|
||||
// 실제 요청에 사용할 URL 결정 (항상 프록시 URL 사용)
|
||||
const useUrl = usingProxy ? proxyUrl : supabaseUrl;
|
||||
|
||||
// URL에 auth/v1이 이미 포함되어있는지 확인
|
||||
const baseUrl = useUrl.includes('/auth/v1') ? useUrl : `${useUrl}/auth/v1`;
|
||||
|
||||
// 토큰 엔드포인트 경로
|
||||
const tokenUrl = `${baseUrl}/token?grant_type=password`;
|
||||
|
||||
console.log('로그인 API 요청 URL:', tokenUrl);
|
||||
|
||||
// 로그인 요청 보내기
|
||||
const response = await fetch(tokenUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'apikey': supabaseKey
|
||||
},
|
||||
body: JSON.stringify({ email, password })
|
||||
// Supabase Cloud를 통한 로그인 요청
|
||||
const { data, error } = await supabase.auth.signInWithPassword({
|
||||
email,
|
||||
password
|
||||
});
|
||||
|
||||
// 응답 상태 확인 및 로깅
|
||||
console.log('로그인 응답 상태:', response.status);
|
||||
|
||||
// HTTP 상태 코드 확인
|
||||
if (response.status === 401) {
|
||||
console.log('로그인 실패: 인증 오류');
|
||||
showAuthToast('로그인 실패', '이메일 또는 비밀번호가 올바르지 않습니다.', 'destructive');
|
||||
return {
|
||||
error: { message: '인증 실패: 이메일 또는 비밀번호가 올바르지 않습니다.' },
|
||||
user: null
|
||||
};
|
||||
}
|
||||
|
||||
if (response.status === 404) {
|
||||
console.warn('API 경로를 찾을 수 없음 (404). 새 엔드포인트 시도 중...');
|
||||
// 오류 응답 처리
|
||||
if (error) {
|
||||
console.error('로그인 오류:', error);
|
||||
|
||||
// 대체 엔드포인트 시도 (/token 대신 /signin)
|
||||
const signinUrl = `${baseUrl}/signin`;
|
||||
// 오류 메시지 포맷팅
|
||||
let errorMessage = error.message;
|
||||
|
||||
try {
|
||||
const signinResponse = await fetch(signinUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'apikey': supabaseKey
|
||||
},
|
||||
body: JSON.stringify({ email, password })
|
||||
});
|
||||
|
||||
console.log('대체 로그인 경로 응답 상태:', signinResponse.status);
|
||||
|
||||
if (signinResponse.status === 404) {
|
||||
showAuthToast('로그인 실패', '서버 설정을 확인하세요: 인증 API 경로를 찾을 수 없습니다.', 'destructive');
|
||||
return {
|
||||
error: { message: '서버 설정 문제: 인증 API 경로를 찾을 수 없습니다. Supabase URL을 확인하세요.' },
|
||||
user: null
|
||||
};
|
||||
}
|
||||
|
||||
// 대체 응답 처리
|
||||
const signinData = await parseResponse(signinResponse);
|
||||
if (signinData.error) {
|
||||
showAuthToast('로그인 실패', signinData.error, 'destructive');
|
||||
return { error: { message: signinData.error }, user: null };
|
||||
}
|
||||
|
||||
if (signinData.access_token) {
|
||||
await supabase.auth.setSession({
|
||||
access_token: signinData.access_token,
|
||||
refresh_token: signinData.refresh_token || ''
|
||||
});
|
||||
|
||||
const { data: userData } = await supabase.auth.getUser();
|
||||
showAuthToast('로그인 성공', '환영합니다!');
|
||||
return { error: null, user: userData.user };
|
||||
}
|
||||
} catch (altError) {
|
||||
console.error('대체 로그인 엔드포인트 오류:', altError);
|
||||
if (error.message.includes('Invalid login credentials')) {
|
||||
errorMessage = '이메일 또는 비밀번호가 올바르지 않습니다.';
|
||||
} else if (error.message.includes('Email not confirmed')) {
|
||||
errorMessage = '이메일 인증이 완료되지 않았습니다. 이메일을 확인해주세요.';
|
||||
}
|
||||
|
||||
showAuthToast('로그인 실패', '서버 설정을 확인하세요: 인증 API 경로를 찾을 수 없습니다.', 'destructive');
|
||||
return {
|
||||
error: { message: '서버 경로를 찾을 수 없습니다. Supabase URL을 확인하세요.' },
|
||||
user: null
|
||||
};
|
||||
}
|
||||
|
||||
// 응답 처리
|
||||
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?.error) {
|
||||
const errorMessage = responseData.error_description || responseData.error;
|
||||
showAuthToast('로그인 실패', errorMessage, 'destructive');
|
||||
return { error: { message: errorMessage }, user: null };
|
||||
}
|
||||
|
||||
// 로그인 성공 응답 처리
|
||||
if (response.ok && responseData?.access_token) {
|
||||
try {
|
||||
// 로그인 성공 시 Supabase 세션 설정
|
||||
await supabase.auth.setSession({
|
||||
access_token: responseData.access_token,
|
||||
refresh_token: responseData.refresh_token || ''
|
||||
});
|
||||
|
||||
// 사용자 정보 가져오기
|
||||
const { data: userData } = await supabase.auth.getUser();
|
||||
|
||||
console.log('로그인 성공:', userData);
|
||||
|
||||
showAuthToast('로그인 성공', '환영합니다!');
|
||||
|
||||
return { error: null, user: userData.user };
|
||||
} catch (sessionError) {
|
||||
console.error('세션 설정 오류:', sessionError);
|
||||
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 };
|
||||
}
|
||||
// 로그인 성공 처리
|
||||
if (data && data.user) {
|
||||
console.log('로그인 성공:', data.user);
|
||||
showAuthToast('로그인 성공', '환영합니다!');
|
||||
return { error: null, user: data.user };
|
||||
} else {
|
||||
// 오류 응답이나 예상치 못한 응답 형식 처리
|
||||
console.error('로그인 오류 응답:', responseData);
|
||||
|
||||
const errorMessage = responseData?.error_description ||
|
||||
responseData?.error ||
|
||||
responseData?.message ||
|
||||
'로그인에 실패했습니다. 이메일과 비밀번호를 확인하세요.';
|
||||
|
||||
showAuthToast('로그인 실패', errorMessage, 'destructive');
|
||||
return { error: { message: errorMessage }, user: null };
|
||||
// 사용자 정보가 없는 경우 (드문 경우)
|
||||
console.warn('로그인 성공했지만 사용자 정보가 없습니다');
|
||||
showAuthToast('로그인 부분 성공', '로그인은 성공했지만 사용자 정보를 가져오지 못했습니다.', 'default');
|
||||
return { error: { message: '사용자 정보 조회 실패' }, user: null };
|
||||
}
|
||||
} catch (fetchError) {
|
||||
console.error('로그인 요청 중 fetch 오류:', fetchError);
|
||||
} catch (error: any) {
|
||||
console.error('로그인 요청 중 예외:', error);
|
||||
const errorMessage = error.message || '로그인 중 오류가 발생했습니다.';
|
||||
|
||||
// 오류 발생 시 프록시 설정 확인 정보 출력
|
||||
const usingProxy = isCorsProxyEnabled();
|
||||
const proxyType = getProxyType();
|
||||
console.log(`오류 발생 시 CORS 설정 - 프록시 사용: ${usingProxy ? '예' : '아니오'}, 타입: ${proxyType}`);
|
||||
|
||||
// Cloudflare 프록시 추천 메시지 추가
|
||||
const errorMessage = handleNetworkError(fetchError);
|
||||
let enhancedMessage = errorMessage;
|
||||
|
||||
if (!usingProxy || proxyType !== 'cloudflare') {
|
||||
enhancedMessage = `${errorMessage} (설정에서 Cloudflare CORS 프록시 사용을 권장합니다)`;
|
||||
}
|
||||
|
||||
showAuthToast('로그인 요청 실패', enhancedMessage, 'destructive');
|
||||
|
||||
return { error: { message: enhancedMessage }, user: null };
|
||||
showAuthToast('로그인 요청 실패', errorMessage, 'destructive');
|
||||
return { error: { message: errorMessage }, user: null };
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user