auth in nextjs
Unanswered
West African Lion posted this in #help-forum
West African LionOP
with the cache component enable and the proxy.ts file the auth has now a bad user experience, when user are log in and go to the login page they see a loading state and then are redirected
40 Replies
this depends a lot on the implementation. Can you show us how you handle authentication in both the page and the proxy?
West African LionOP
yes sure (thank you!)
import { NextRequest, NextResponse } from "next/server";
import { getSessionCookie } from "better-auth/cookies";
const protectedRoutes = [
"/project",
"/project/[slug]/tasks",
"/project/[slug]/editor",
];
function matchesRoute(path: string, route: string): boolean {
if (path === route) return true;
const pattern = route.replace(/\[[\w]+\]/g, "[^\\/]+").replace(/\//g, "\\/");
const regex = new RegExp(`^${pattern}$`);
return regex.test(path);
}
export default async function proxy(req: NextRequest) {
const path = req.nextUrl.pathname;
const isProtectedRoute = protectedRoutes.some((route) =>
matchesRoute(path, route)
);
const sessionCookie = getSessionCookie(req);
if (isProtectedRoute && !sessionCookie) {
return NextResponse.redirect(new URL("/get-started", req.nextUrl));
}
return NextResponse.next();
}
export const config = {
matcher: ["/((?!api|_next/static|_next/image|privacy|terms|.*\\.png$).*)"],
};import GetStartedContent from "@/features/auth/components/GetStartedContent";
import { verifyPublicAccess } from "@/lib/auth/dal";
export default async function Onboarding() {
await verifyPublicAccess();
return <GetStartedContent />;
}export const getSession = cache(async () => {
const h = await headers();
const session = await auth.api.getSession({ headers: h });
return session;
});
// Use this on public pages (like home) to redirect authenticated users
export const verifyPublicAccess = cache(async () => {
const session = await getSession();
if (session?.user) {
if (!session.user.isProfileComplete) {
redirect("/get-started/profile");
} else {
redirect("/project");
}
}
return null; // No session, user can stay on public page
});so basically the proxy do a optimistic check to see if there is a cookie and hen on each page we verify the cookie
(Might be a mistake here since I'm in mobile with a very low battery on a bike)
The
The
protectedRoutes and config.matcher doesn't seem to overlap at all?West African LionOP
yeah that's normal the
config.matcher is for saying where the proxy should not run@West African Lion
import GetStartedContent from "@/features/auth/components/GetStartedContent";
import { verifyPublicAccess } from "@/lib/auth/dal";
export default async function Onboarding() {
await verifyPublicAccess();
return <GetStartedContent />;
}
Saint Hubert Jura Hound
But you said the issue was on the login page?
@Saint Hubert Jura Hound But you said the issue was on the login page?
West African LionOP
yeah on the get started page
well the thing is that there is to type of page: the one only authenticated users can access and the one only not authenticated user can access
an the proxy make sure that when a user has no cookie and go on a page that only authenticated user can access it direcly block the access so we don't see any loading state, but it only work in that sense so when a user that has a cookie and go for example in the get-started page the proxy will not do anything so we have the in page verification to see if the user is sign in but the user will see the loading state of the get-started page
@Silver Marten might have the answer
do you have it @Saint Hubert Jura Hound
Saint Hubert Jura Hound
Dont ping random ppl pls
West African LionOP
no but delba did a video on it a year ago so she might have the answer
Saint Hubert Jura Hound
Also we cant see any loading state or suspense in the files u provided so its impossible to know where that comes from. But its expected behavior if the check ur awaiting is in a suspense
@West African Lion no but delba did a video on it a year ago so she might have the answer
Saint Hubert Jura Hound
Doesnt matter
West African LionOP
yes there is a loading.tsx file for the get-started page
it is needed since we get the header() in the page
it's because we use cache component
Saint Hubert Jura Hound
Okay so the loading state is expected. Im not sure how you would avoid that though. Never used cache components myself but im pretty sure it will complain/error if you move the verifypublicaccess check outide of the suspense boundary
So i think ur options are either to move the redirect for some of those public pages to proxy.ts, hide the loading state on that specfic page only, or not care if the user sees a loading state if they dont have access and will get redirected anyway
I would probably just stick to the 3rd option..
West African LionOP
really? you don't think this is bad user experience?
Saint Hubert Jura Hound
Personally i dont, especially since the alternative here would just be a blank screen for the user for a second
The check needs to happen either way so
West African LionOP
okay thanks! and you don't use cache component?
can I know why?
Saint Hubert Jura Hound
Not yet but i plan to move to them soon. Just been a bit busy and i didnt know if they were fully ready for production use yet. Was waiting a bit to understand how they work better too
I dont see anything wrong with them or something. They seem good
verifypublicaccess should not be cached
West African LionOP
I understand, well thank you for everything!
@Dreamgineer verifypublicaccess should not be cached
West African LionOP
really? that's what they do here: https://nextjs.org/docs/app/guides/authentication#creating-a-data-access-layer-dal
@Dreamgineer verifypublicaccess should not be cached
Saint Hubert Jura Hound
It is indeed fine to be cached since react
cache works on a per request basisi could be wrong since my database latency is only a fraction of a millisecond
@West African Lion I understand, well thank you for everything!
Saint Hubert Jura Hound
No worries, if i find another way to get around this when i start using cache componets ill let u know lol
@Saint Hubert Jura Hound No worries, if i find another way to get around this when i start using cache componets ill let u know lol
West African LionOP
thanks your the best! let's keep contact if that okay?
@West African Lion <@608939079790231592> might have the answer
Please dont ping random people. its against the rule.