본문 바로가기

TIL

TIL - 소셜 로그인 리다이렉트 트러블 슈팅 (Next.js, supabase)

트러블 슈팅 과정 요약

문제 발견: 기존의 클라이언트 측 리다이렉션 방식에서 CORS 문제로 인해 리다이렉션이 실패했습니다.

문제 분석: Supabase 미들웨어가 CORS 문제를 해결하지 못했습니다.

해결 방법: 클라이언트 측에서 직접 리다이렉션하도록 코드 변경을 시도했으나, 최종적으로 서버 측에서 직접 리다이렉션 처리로 변경했습니다.

결과: 서버 측에서 직접 리다이렉션하여 CORS 문제 없이 소셜 로그인 리다이렉션이 정상적으로 작동했습니다.

시도한 접근 방식

  1. CORS 문제 해결 시도: Supabase의 미들웨어에서 CORS 문제를 처리한다고 했지만, 실제로 처리되지 않았습니다.
  2. 리디렉션 URL 확인: Supabase의 리디렉션 URL을 로그창에서 확인하고, 해당 URL을 반환하도록 변경했습니다.
  3. 직접 리다이렉션 시도: 서버에서 데이터를 반환하는 대신, 클라이언트 측에서 직접 리다이렉션하도록 변경했습니다.

코드 내용

기존 코드에서는 axios를 사용하여 URL을 받아온 후 클라이언트 측에서 리다이렉션을 처리했습니다.

// 소셜 로그인
signInWithOAuth = async (provider: Provider): Promise<any> => {
  try {
    const response = await axios.get(`${this.baseUrl}/social/${provider}`, {
      params: { provider },
    });
    window.location.href = response.data.url;
  } catch (error) {
    if (axios.isAxiosError(error)) {
      throw new Error(error.response?.data?.error || error.message);
    }
    throw error;
  }
};

 

해결한 코드에서는 axios를 사용하지 않고, 클라이언트 측에서는 서버의 API 엔드포인트로 리다이렉션하도록 변경했습니다. 

 

// 소셜 로그인
signInWithOAuth = async (provider: Provider): Promise<void> => {
  try {
    window.location.href = `${this.baseUrl}/social/${provider}?provider=${provider}`;
  } catch (error) {
    throw error;
  }
};

 

import { createClient } from '@/supabase/server';
import { Provider } from '@supabase/supabase-js';
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const provider = searchParams.get('provider') as Provider;

  console.log(provider);

  if (!provider) {
    return NextResponse.json({ error: 'Provider is required' }, { status: 400 });
  }

  const supabase = createClient();

  try {
    const { data, error } = await supabase.auth.signInWithOAuth({
      provider: provider,
      options: {
        redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/api/auth/callback`,
      },
    });

    if (error) throw error;

    if (data && data.url) {
      console.log(data.url);
      return NextResponse.redirect(data.url);
    } else {
      throw new Error('No URL returned from Supabase');
    }
  } catch (error) {
    console.error('OAuth error:', error);
    return NextResponse.json({ error: 'Failed to initiate OAuth flow' }, { status: 500 });
  }
}

 

그리고 서버 측에서는 Supabase를 통해 OAuth URL을 생성하고, 클라이언트를 해당 URL로 다시 리다이렉션하는 방식으로 최종 변경되었습니다.

 

결론

이 트러블 슈팅 과정을 통해 클라이언트와 서버 간의 CORS 문제를 해결하는 방법을 배웠습니다. 특히, 클라이언트 측에서의 리다이렉션 대신 서버 측에서 직접 리다이렉션을 처리하는 것이 더 안정적이라는 것을 깨달았습니다. 최종적으로, 서버 측에서 직접 리다이렉션하여 소셜 로그인 과정이 원활하게 작동하게 되었습니다.