강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

jjk5050123님의 프로필 이미지
jjk5050123

작성한 질문수

한 입 크기로 잘라먹는 실전 프로젝트 - SNS 편

(6.11) 회원가입시 프로필 정보 자동 생성하기

OAuth 프로필 생성 관련 질문입니다.

작성

·

25

0

안녕하세요 강의 정말 잘 듣고있습니다.

현재 강의를 무한 중첩 댓글 구현하기까지 수강했습니다!

테스트를 위해 여러가지 사항들을 직접 체크하고있는데 Github로 로그인한 사용자의 정보들(avatar_url, name)들은 기본적으로 사용하지 않고 랜덤한 닉네임과 기본 아바타 이미지가 나오는게 정상 동작일까요?

제가 이해한 흐름은 다음과 같습니다.

1. Github(OAuth) 로그인
2. Supabase Authentication > Users에 사용자 생성 (profile 테이블에는 아직 생성 되지 않음)
3. SessionProvider에서 useProfileData 호출

export default function SessionProvider({ children }: { children: ReactNode }) {
  const session = useSession();
  const setSession = useSetSession();
  const isSessionLoaded = useIsSessionLoaded();

  const { data: profile, isLoading: isProfileLoading } = useProfileData(
    session?.user.id,
  );

  useEffect(() => {
    supabase.auth.onAuthStateChange((event, session) => {
      setSession(session);
    });
  }, []);

  if (!isSessionLoaded) return <GlobalLoader />;
  if (isProfileLoading) return <GlobalLoader />;

  return children;
}

4. fetchProfile(userId) 실행

export async function fetchProfile(userId: string) {
  const { data, error } = await supabase
    .from("profile")
    .select("*")
    .eq("id", userId)
    .single();

  if (error) throw error;
  return data;
}
  1. Supabase Table Editor > profile 에는 아무런 결과가 저장되어 있지 않기 때문에
    PostgrestError: PGRST116 에러 발생

 

  1. useProfileData catch 블록 실행 → createProfile 호출

 

  1. 랜덤한 닉네임 + avatar_url이 기본으로 저장

 

만약 제가 이해한 흐름이 맞다면 어떤 방법을 써야할까요?
제일 먼저 드는 생각은 createProfile에 session을 매개변수로 받아서 session.user.user_metadata.full_nameavatar_url을 insert에 넣는걸 생각했습니다.


createProfile

export async function createProfile(userId: string, session?: Session) {
  const { data, error } = await supabase
    .from("profile")
    .insert({
      id: userId,
      // ↓ 여기 수정 했어용
      nickname: session?.user.user_metadata?.full_name || getRandomNickname(), 
      avatar_url: session?.user.user_metadata?.avatar_url || null,
    })
    .select()
    .single();

  if (error) throw error;
  return data;
}

 

use-profile-data.ts

export function useProfileData(userId?: string) {
  const session = useSession();
  const isMine = userId === session?.user.id;

  return useQuery({
    queryKey: QUERY_KEYS.profile.byId(userId!),
    queryFn: async () => {
      try {
        const profile = await fetchProfile(userId!);
        return profile;
      } catch (error) {
        if (isMine && (error as PostgrestError).code === "PGRST116") {
          return await createProfile(userId!, session!); // 여기 session 추가 했어용
        }
        throw error;
      }
    },
    enabled: !!userId,
  });
}

 

이렇게 코드를 수정하고 profile table을 삭제한 후 다시 Github로 로그인 하면 사용자의 프로필 이미지와 이름이 받아와졌습니다.

더 효율적이거나 더 좋은 방법이 있을까요? 혹은 제가 잘못 알고 있는게 있을까요?

답변 2

0

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

안녕하세요 jjk5050123님 이정환입니다.

우선 GitHub의 정보를 이용하지 않고 서비스 자체의 랜덤한 닉네임을 사용하는것은 본 서비스의 의도된 동작입니다. 무조건 연동 로그인 된 서비스의 계정 정보를 불러와 채워넣을 필요는 없습니다 😀

이 과정에서 만약 GitHub의 정보를 이용해 기본 정보를 채워넣도록 수정하고 싶으시다면 올려주신 코드대로 기능을 수정해 이용하시면 됩니다.

0

안녕하세요, 인프런 AI 인턴입니다. jjk5050123님.

Supabase와 OAuth를 활용한 프로필 생성 과정에서의 흐름과 구현에 대한 질문을 주셨네요. 설명한 흐름은 전반적으로 올바르게 이해하고 계신 것 같습니다. Github와 같은 OAuth 서비스를 통해 로그인한 사용자의 데이터를 Supabase로 가져올 때 부딪히는 문제와 작업 흐름을 설명할 수 있습니다. 핵심 사항을 요약하고 몇 가지 추가적인 정보를 제공하겠습니다.

현재 구현 방식

  1. OAuth 로그인: 사용자 인증이 이루어지고, 이러한 정보는 Supabase Authentication에 저장됨.

  2. 사용자 정보 로딩: SessionProvideruseProfileData를 호출해 사용자 정보를 프로필 테이블에서 조회합니다.

  3. 프로필 생성 로직: fetchProfile 함수는 프로필 테이블을 조회하고, 해당 프로필 정보가 없을 경우 에러를 발생시킵니다. 에러가 발생하면 createProfile 함수를 통해 사용자 프로필을 생성합니다.

  4. 프로필 데이터 삽입: createProfile 함수가 호출되면서 Github에서 제공하는 데이터(full_nameavatar_url)을 통해 프로필이 생성됩니다.

개선 및 검토 사항

  1. 초기 프로필 데이터 활용:

    • 종종 OAuth 제공자가 제공하는 메타데이터(예: full_name, avatar_url) 정보를 초기 프로필 생성 시 활용하는 것이 일반적입니다. 이미 구현하신 방법대로 createProfile 함수에서 이를 호출하여 처리하면 무난할 것입니다.
  2. 에러 핸들링 및 로깅:

    • 사용자의 프로필을 만들기 전에 PostgrestError를 포함하여 오류 상황을 잘 핸들링하며 로그를 남기는 것도 좋은 방식입니다. 이렇게 하면 문제 발생 시 추적이 용이합니다.
  3. 성능 최적화:

    • 프로필을 미리 판단하여 로딩 시점을 최적화하거나, 언제 프로필을 생성할 지에 대한 로직을 재검토할 수 있습니다. 사용자가 앱에 처음 접근할 때 미리 생성해두어 많은 HTTP 요청을 줄일 수도 있습니다.
  4. 보안 고려사항:

    • 프로필 생성 시 사용하기 전, 외부에서 온 데이터를 검증하고 유효성을 검사하는 것도 중요합니다. 이는 데이터 무결성과 보안을 보장하는 데 필수적입니다.
  5. 다른 개선 방안:

    • 초기 로그인 시점에 한 번 Create API를 호출하여, 유효한 프로필이 생성되지 않도록 하는 것도 방법입니다.

다른 유사한 질문과 해결 방법은 아래 링크에서 확인해 볼 수 있습니다:

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

jjk5050123님의 프로필 이미지
jjk5050123

작성한 질문수

질문하기