카테고리 없음
nextAuth supabase 소셜로그인 상태유지
윤미주
2024. 4. 4. 17:27
supabase에 이메일 값 전달
import { getLoginUserType } from '@/types/authUser/authUserTypes';
import { supabase } from '../supabase/supabase';
export const getUserIdByEmail = async (email: string): Promise<getLoginUserType> => {
const { data, error } = await supabase //
//테이블 이름
.from('users')
// 컬럼
.select('user_id')
//필터
.eq('email', email as string)
.single();
if (error || !data) throw error;
return data;
};
쿼리를 이용해 email 전달
import { getUserIdByEmail } from '@/app/api/userEmail/loginUserId';
import { getLoginUserType } from '@/types/authUser/authUserTypes';
import { useQuery } from '@tanstack/react-query';
export function useReadLoginUserId(email: string) {
return useQuery<getLoginUserType, Error>({
queryKey: ['LoginUserId', { email }],
queryFn: () => getUserIdByEmail(email),
//이메일 존재할때만 쿼리 실행
enabled: !!email
});
}
로그인 상태유지
nextAuth에서 주는 세션으로 로그인 상태유지를 하려고 하는 경우
새로고침 시 세션에 값을 불러오기 전까지 상태유지가 잠시 풀리는 경우가 발생
브라우저스토리지, 로컬스토리지, 세션스토리지 에 세션에서 주는 유저의 email을 담아서 사용
로그인 시 세션에 저장되는 값을 세션스토리지에 담기
'use client';
import { useEffect } from 'react';
import { useSession } from 'next-auth/react';
import { supabase } from '@/app/api/supabase/supabase';
export function useUserEmail() {
const { data: session } = useSession();
useEffect(() => {
// 최초 실행 시 현재 세션의 이메일 주소를 sessionStorage에 저장
const userEmail = session?.user?.email;
if (userEmail) {
sessionStorage.setItem('userEmail', userEmail);
}
// Supabase 인증 상태 변경 시 콜백 함수
// supabase.auth.onAuthStateChange를 통해 생성된 리스는 사용자 인증상태가 변할 떄마다 실행됨.
// 생명 주기동안 계속 실행됙 ㅣ때문에 사용자가 해당 페이지를 벗어나면 해제해 줘야함 (메모리누수)
const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => {
const currentEmail = session?.user?.email;
if (event === 'SIGNED_IN' && currentEmail) {
// 로그인 시 이메일 주소가 있으면 저장
sessionStorage.setItem('userEmail', currentEmail);
}
});
return () => {
// 정리해주는 코드
// session이 변경되어 useEffect가 재실행 되기전에 깨깟이 정리해줌 (메모리 누수 방지)
authListener.subscription.unsubscribe();
};
}, [session]);
const userEmail = sessionStorage.getItem('userEmail');
return userEmail;
}
로그아웃 시 세션스토리지 값 지우기
'use client';
import { useUserEmail } from '@/hooks/useLogin/useUserEmail';
import { signOut } from 'next-auth/react';
import Link from 'next/link';
export default function LoginState() {
const userEmail = useUserEmail();
const handleLogout = async () => {
sessionStorage.removeItem('userEmail');
await signOut({ redirect: true, callbackUrl: '/' });
};
return <div>{userEmail ? <button onClick={handleLogout}>Logout</button> : <Link href="/hello">Login</Link>}</div>;
}