nextjs에서 제공하는 middleware를 사용하여 supabase의 인증 access token을 쿠키로 넘겨줘야 했는데 이 부분에서 굉장히 애를 많이 먹었다.
결론적으로, 아래와 같은 내용들을 알게 됐다.
위 내용을 정리해서 코드를 작성한 내용은 다음과 같다
// middleware.ts
import { createMiddlewareClient } from "@supabase/auth-helpers-nextjs";
import { NextRequest, NextResponse } from "next/server";
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
const supabase = createMiddlewareClient({ req: request, res: response });
const {
data: { session },
} = await supabase.auth.getSession();
const { pathname } = request.nextUrl;
if (
!session &&
(pathname.startsWith("/dashboard") || pathname.startsWith("/metaverse"))
) {
console.log("세션이 없는데 dashboard, metaverse에 들어옴");
return NextResponse.redirect(new URL("/signin", request.nextUrl.basePath));
}
if (
session &&
(pathname.startsWith("/signin") || pathname.startsWith("/signup"))
) {
console.log("세션은 있는데 signin singup 페이지에 들어옴");
return NextResponse.redirect(new URL("/", request.nextUrl.basePath));
}
return response;
}
export const config = {
matcher: [
"/dashboard/:path*",
"/metaverse/:path*",
"/signin/:path",
"/signup/:path",
],
};
// checkUserSession 컴포넌트
import { getUserSessionHandler } from "@/api/supabase/auth";
import { supabase } from "@/supabase/supabase";
import useAuth from "@/zustand/authStore";
import { useEffect } from "react";
export default function CheckUserSession() {
const { logout, login } = useAuth();
useEffect(() => {
const channel = supabase.auth.onAuthStateChange((event, session) => {
console.log(event);
if (event === "INITIAL_SESSION" || event === "SIGNED_IN") {
if (!session) return;
getUserSessionHandler(session)
.then((user) => {
login(user);
})
.catch((error) => {
console.log(error);
});
// 여기가 실행이 안됨
} else if (event === "SIGNED_OUT") {
logout();
}
});
return () => {
channel.data.subscription.unsubscribe();
};
}, []);
return <></>;
}
export const getServerSideProps = async () => {
return {
props: {},
};
};
// auth.ts
export const getUserSessionHandler = async (session: Session): Promise<any> => {
const { data: currentUserInfo, error } = await supabase
.from("users")
.select(`*`)
.eq("id", session.user.id!)
.single();
if (error) return Promise.reject(error); // 여기서 오류를 제대로 뱉질 않는다
return currentUserInfo;
};