I'm struggling with refreshing the access token. I have a custom BE (in Django) which handles authentication but in the FE, since I can only update cookies on server actions or route handlers.
When I log in, I store the cookies like this, in a server action under actions/auth:
const setSessionCookies = (session: UserState) => {
const sessionString = JSON.stringify(session);
cookies().set('session', sessionString, {
expires: new Date(session.refresh_expiration || ''),
httpOnly: true,
});
};
export const signIn = async (email: string, password: string): Promise<UserState>=> {
const { data } = await signInService(email, password);
setSessionCookies(data);
return data;
};
To refresh the token I have the following server action:
export const refreshToken = async () => {
const currentSessionCookies = cookies().get('session')?.value;
if (currentSessionCookies) {
const currentSession: UserState = JSON.parse(currentSessionCookies);
const { data } = await refreshTokenService(currentSession.refresh || '');
if (data) {
currentSession.access = data.access;
currentSession.access_expiration = data.access_expiration;
setSessionCookies(currentSession);
return data;
}
}
};
I have tried it in three ways:
- Creating a
middleware.tsfile, but I get the error that says cookies can't be set outside of server actions or route handlers:
export async function middleware(request: NextRequest) {
const sessionCookie = cookies().get('session')?.value;
if (sessionCookie) {
const session: UserState = JSON.parse(sessionCookie);
if (session.refresh_expiration && new Date(session.refresh_expiration).getTime() <= Date.now()) {
await signOut();
return NextResponse.redirect(new URL('/', request.url));
} else if (session.access_expiration && new Date(session.access_expiration).getTime() <= Date.now()) {
await refreshToken();
return NextResponse.next();
}
}
return NextResponse.next();
}
- Creating an interceptor with axios to handle it in the same way as the middleware, but get the same error:
api.interceptors.request.use(...); - Creating an api route:
api/auth/refreshto try updating it from there, but in this case the cookies are empty when I docookies().getAll(), so not sure how to update it there.
Any thoughts? I've placed 'use server' at the top of actions/auth to make sure those are server actions, but when called from middleware or axios interceptor, it seems i can't update the cookies.