feat: integrate session management with AppWrapper and update axios interceptor for token handling

This commit is contained in:
Rémi 2025-01-06 03:15:01 +01:00
parent 9f2ae08f1a
commit dc858227fa
5 changed files with 17 additions and 7 deletions

View File

@ -1,16 +1,19 @@
"use client"; "use client";
import { NextUIProvider } from "@nextui-org/react"; import { NextUIProvider } from "@nextui-org/react";
import { Session } from "next-auth";
import { SessionProvider } from "next-auth/react"; import { SessionProvider } from "next-auth/react";
import { ThemeProvider as NextThemesProvider } from "next-themes"; import { ThemeProvider as NextThemesProvider } from "next-themes";
export default function AppWrapper({ export default function AppWrapper({
session,
children, children,
}: { }: {
session: Session | null;
children: React.ReactNode; children: React.ReactNode;
}) { }) {
return ( return (
<SessionProvider> <SessionProvider session={session} refetchOnWindowFocus={false}>
<NextUIProvider> <NextUIProvider>
<NextThemesProvider attribute="class" defaultTheme="dark"> <NextThemesProvider attribute="class" defaultTheme="dark">
{children} {children}

View File

@ -1,15 +1,18 @@
import { getSession } from "@/authOptions";
import AppWrapper from "./components/AppWrapper"; import AppWrapper from "./components/AppWrapper";
import "./globals.css"; import "./globals.css";
export default function RootLayout({ export default async function RootLayout({
children, children,
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const session = await getSession()
return ( return (
<html lang="fr" suppressHydrationWarning> <html lang="fr" suppressHydrationWarning>
<body> <body>
<AppWrapper>{children}</AppWrapper> <AppWrapper session={session}>{children}</AppWrapper>
</body> </body>
</html> </html>
); );

View File

@ -12,19 +12,23 @@ export const axiosInstance = axios.create({
}); });
axiosInstance.interceptors.request.use(async (config) => { axiosInstance.interceptors.request.use(async (config) => {
// If the access token is still valid, use it
if (tokenExpirationAt && moment().isBefore(tokenExpirationAt)) { if (tokenExpirationAt && moment().isBefore(tokenExpirationAt)) {
config.headers.Authorization = `Bearer ${cachedAccessToken}`; config.headers.Authorization = `Bearer ${cachedAccessToken}`;
return config; return config;
} }
// Otherwise, get a new access token
const session = await getSession(); const session = await getSession();
if (!session) { if (!session) {
throw new Error("User is not authenticated"); throw new Error("User is not authenticated");
} }
// Cache the new access token
cachedAccessToken = session.accessToken; cachedAccessToken = session.accessToken;
tokenExpirationAt = moment(session.accessTokenExpires); tokenExpirationAt = moment(session.accessTokenExpires);
// Use the new access token
config.headers.Authorization = `Bearer ${cachedAccessToken}`; config.headers.Authorization = `Bearer ${cachedAccessToken}`;
return config; return config;
}); });

View File

@ -1,3 +0,0 @@
export const UppercaseFirstLetter = (str: string) => {
return str.slice(0, 1).toLocaleUpperCase() + str.slice(1);
};

View File

@ -1,9 +1,10 @@
import axios from "axios"; import axios from "axios";
import moment from "moment"; import moment from "moment";
import { AuthOptions, Session } from "next-auth"; import { AuthOptions, getServerSession, Session } from "next-auth";
import { JWT } from "next-auth/jwt"; import { JWT } from "next-auth/jwt";
import jsonwebtoken from "jsonwebtoken"; import jsonwebtoken from "jsonwebtoken";
import { JWTDecoded } from "./app/types/next-auth"; import { JWTDecoded } from "./app/types/next-auth";
import { cache } from "react";
moment.locale("fr"); moment.locale("fr");
@ -120,3 +121,5 @@ const refreshAccessToken = async (token: JWT): Promise<JWT> => {
refreshToken: response.data.refresh_token, refreshToken: response.data.refresh_token,
}; };
}; };
export const getSession = cache(() => getServerSession());