programming/React
Auth.js signIn 완료 후 session 이 여전히 null (수동 리프레시를 해야만 session 이 업데이트 됨)
euuuuuz:
2024. 10. 30. 09:23
참고 : https://github.com/nextauthjs/next-auth/issues/9504#issuecomment-2326123445
[BEFORE]
layout.tsx
import Footer from "@/components/footer";
import Header from "@/components/header";
import ReactQueryProvider from "@/components/provider/ReactQueryProvider";
import type { Metadata } from "next";
import { SessionProvider } from "next-auth/react";
import localFont from "next/font/local";
import { ToastContainer } from "react-toastify";
import "./globals.scss";
import "react-toastify/dist/ReactToastify.css";
const pretendard = localFont({
src: "./fonts/PretendardVariable.woff2",
display: "swap",
weight: "45 920",
variable: "--font-pretendard",
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="kr">
<body className={`${pretendard.variable} font-pretendard antialiased`}>
<ReactQueryProvider>
<SessionProvider>
<div id="modal-root" />
<ToastContainer />
<Header />
{children}
<Footer />
</SessionProvider>
</ReactQueryProvider>
</body>
</html>
);
}
[AFTER]
layout.tsx
import Footer from "@/components/footer";
import Header from "@/components/header";
import ReactQueryProvider from "@/components/provider/ReactQueryProvider";
import type { Metadata } from "next";
import localFont from "next/font/local";
import { ToastContainer } from "react-toastify";
import "./globals.scss";
import { auth } from "@/auth";
import AuthSessionProvider from "@/components/provider/AuthSessionProvider";
import "react-toastify/dist/ReactToastify.css";
const pretendard = localFont({
src: "./fonts/PretendardVariable.woff2",
display: "swap",
weight: "45 920",
variable: "--font-pretendard",
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const session = await auth();
const sessionKey = new Date().valueOf();
return (
<html lang="kr">
<body className={`${pretendard.variable} font-pretendard antialiased`}>
<ReactQueryProvider>
<AuthSessionProvider session={session} sessionKey={sessionKey}>
<div id="modal-root" />
<ToastContainer />
<Header />
{children}
<Footer />
</AuthSessionProvider>
</ReactQueryProvider>
</body>
</html>
);
}
provider/AuthSessionProvider 프로바이더 컴포넌트를 생성
// AuthSessionProvider.tsx
"use client";
import { SessionProvider } from "next-auth/react";
import { useMemo } from "react";
export default function AuthSessionProvider({ children, ...props }: any) {
const { session, sessionKey } = props;
const memoizedSessionKey = useMemo(() => {
return sessionKey;
}, [session]);
return (
<SessionProvider key={memoizedSessionKey} session={session}>
{children}
</SessionProvider>
);
}
signIn 성공 후 메인 페이지로 리다이렉트 되었을때,
클라이언트 컴포넌트에서 useSession() 으로 호출하는 session 데이터나,
서버 컴포넌트에서 auth() / getSession() 등으로 호출하는 session 데이터 모두 바로 authorized 상태와 유저 정보가 업데이트 된다