`UseRouter` Caches the Cookies should I use `redirect`?
Answered
Sun bear posted this in #help-forum
Sun bearOP
Login Flow:
- Successful login saves a cookie with user information.
- I programmatically redirect to the dashboard using
Logout Flow:
- Logout removes the cookie.
- The user is redirected to the login page using
Even after logging out (and removing the cookie), if the user had previously accessed the dashboard, they can still access it despite not being authenticated.
The documentation indicates that the Next.js Router Cache https://nextjs.org/docs/app/building-your-application/caching#router-cache cannot be disabled entirely, with only "hacky refreshes" as a workaround Router Cache. This approach feels wrong . I explored using server-side redirection within a login flow through a server action (redirect). This resolves the inconsistency but doesn't this add an extra server call, potentially impacting performance, especially for a large-scale system with a separate backend?
Is there a recommended approach to address these navigation issues while maintaining optimal performance and adhering to best practices for a large-scale Next.js application? Can we leverage the Router Cache effectively while ensuring proper authentication checks?
- Successful login saves a cookie with user information.
- I programmatically redirect to the dashboard using
router.push('/dashboard'). However, this redirection is unreliable, sometimes working and sometimes not.Logout Flow:
- Logout removes the cookie.
- The user is redirected to the login page using
router.push('login'), which works as expected.Even after logging out (and removing the cookie), if the user had previously accessed the dashboard, they can still access it despite not being authenticated.
The documentation indicates that the Next.js Router Cache https://nextjs.org/docs/app/building-your-application/caching#router-cache cannot be disabled entirely, with only "hacky refreshes" as a workaround Router Cache. This approach feels wrong . I explored using server-side redirection within a login flow through a server action (redirect). This resolves the inconsistency but doesn't this add an extra server call, potentially impacting performance, especially for a large-scale system with a separate backend?
'use server'
import { redirect } from 'next/navigation'
export async function navigate(data: string) {
redirect(data);
}Is there a recommended approach to address these navigation issues while maintaining optimal performance and adhering to best practices for a large-scale Next.js application? Can we leverage the Router Cache effectively while ensuring proper authentication checks?
Answered by Ray
you should use server action for the logout and redirect after that, which will invalidate the router cache when you set/delete the cookies in the server action
33 Replies
Sun bearOP
any idea how to fix it?
@Sun bear Login Flow:
- Successful login saves a cookie with user information.
- I programmatically redirect to the dashboard using `router.push('/dashboard')`. However, this redirection is unreliable, sometimes working and sometimes not.
Logout Flow:
- Logout removes the cookie.
- The user is redirected to the login page using `router.push('login')`, which works as expected.
Even after logging out (and removing the cookie), if the user had previously accessed the dashboard, they can still access it despite not being authenticated.
The documentation indicates that the Next.js Router Cache https://nextjs.org/docs/app/building-your-application/caching#router-cache cannot be disabled entirely, with only "hacky refreshes" as a workaround Router Cache. This approach feels wrong . I explored using server-side redirection within a login flow through a server action (redirect). This resolves the inconsistency but doesn't this add an extra server call, potentially impacting performance, especially for a large-scale system with a separate backend?
js
'use server'
import { redirect } from 'next/navigation'
export async function navigate(data: string) {
redirect(data);
}
Is there a recommended approach to address these navigation issues while maintaining optimal performance and adhering to best practices for a large-scale Next.js application? Can we leverage the Router Cache effectively while ensuring proper authentication checks?
you should use server action for the logout and redirect after that, which will invalidate the router cache when you set/delete the cookies in the server action
Answer
if you need to do it on client side, call
router.refresh() after logoutSun bearOP
Thanks @Ray , but does calling it using a server action considered an extra api call? It doesn't seem to be normal does it?
@Sun bear Thanks <@743561772069421169> , but does calling it using a server action considered an extra api call? It doesn't seem to be normal does it?
I don't think there is an extra api call with server action
Sun bearOP
From the docs
?
how do you do the logout logic?
Sun bearOP
const signOut = () => {
Cookies.remove("sm_session");
setSession(sessionNotFound);
router.push("/signin");
};so you do it in the browser?
Sun bearOP
It is inside a context called
AuthProvideryes
Sun bearOP
I have separate backend to handle authentication
the ideal solution would be using server action like this
'use server'
import { redirect } from 'next/navigation'
import { cookies } from 'next/headers'
export async function signOut(data: string) {
// handle logout
cookies().delete("cookie")
redirect(data);
}Sun bearOP
so I refresh inside the signin or before
router.push ?@Sun bear so I refresh inside the signin or before `router.push` ?
const signOut = () => {
Cookies.remove("sm_session");
setSession(sessionNotFound);
router.refresh();
router.push("/signin");
};@Ray the ideal solution would be using server action like this
ts
'use server'
import { redirect } from 'next/navigation'
import { cookies } from 'next/headers'
export async function signOut(data: string) {
// handle logout
cookies().delete("cookie")
redirect(data);
}
Sun bearOP
This looks good. But this makes an extra api call just for navigation
@Ray ts
const signOut = () => {
Cookies.remove("sm_session");
setSession(sessionNotFound);
router.refresh();
router.push("/signin");
};
Sun bearOP
Thanks! Will it invalidate all the routes?
it also delete the cookie
and you can't remove the cookie if the cookies is httponly on browser
Sun bearOP
Okayy that makes sense!
Thank you so much Ray! last question does the
router.refresh() invalidate all routes?@Sun bear Thank you so much Ray! last question does the `router.refresh()` invalidate all routes?
what do you mean all routes? it invalidate the router cache on the client
Sun bearOP
So the router cache is global to all routes? I thought there was a cache for each route 😅
@Sun bear So the router cache is global to all routes? I thought there was a cache for each route 😅
you are talking full route cache which is on the server
and router.fresh() is invalidating the router cache
which is on the client browser
if you need to signout a user on client side, you need
router.refresh()Sun bearOP
Okayy that makes sense. Thanks a bunch Ray!