Next.js Discord

Discord Forum

Next.js 14 App Layout + Server Actions + Protected Routes

Answered
Ichneumonid wasp posted this in #help-forum
Open in Discord
Avatar
Ichneumonid waspOP
Hi! I have the following structure:
πŸ“ app
 | πŸ“ [user]
   | βš›οΈ layout.tsx
   | βš›οΈ page.tsx
 | βš›οΈ layout.tsx
 | βš›οΈ page.tsx

In the app/page.tsx, I'm using Server Actions to redirect when the user is signed in:
// πŸ“ app/page.tsx
const user = await getUser();

if (user) {
   return redirect(`/${user.user_metadata.user_name}`);
}

My question is as follows. I am using app/[user]/layout.tsx to protect paths that are [user]/*:
// πŸ“ app/[user]/layout.tsx
import { getUserData } from "@/server/auth";
import { redirect } from "next/navigation";

const AppLayout = async ({ params }: { params: { user: string } }) => {
  const user = await getUserData(params.user);

  if (!user) {
    return redirect("/auth");
  }
  
  return <div>AppLayout</div>;
};

export default AppLayout;

The app works but I am not clear if it is the right way. Taking into account that the app has multiple protected pages. πŸ€”

- getUserData It's a server action that checks if the user is logged in and if the path.user matches the Supabase getUser username:
export const getUserData = async (username: string) => {
  const user = await getUser();
  if (!user) {
    return redirect("/auth");
  }
  if (user.user_metadata.user_name !== username) {
    return redirect(`/${user.user_metadata.user_name}`);
  }
  return user;
};
Answered by B33fb0n3
your middleware right now only updates the session. Right now, it does not handle the auth process. As I said: If I would be you, I would let my middleware handle the auth process to protect specific routes
View full answer

11 Replies

Avatar
B33fb0n3
If I need to protect data, then I would verify and authenticate my user inside my middleware and check only protected routes thought middleware. The middleware is handled on edge and serverside, so I am able to retrieve the data without a server action.

You might want to do the same, the secure your pages
Avatar
Ichneumonid waspOP
Hii! I'm using the Supabase middleware:
- https://supabase.com/docs/guides/getting-started/tutorials/with-nextjs?queryGroups=language&language=ts#nextjs-middleware
import { type NextRequest } from "next/server";
import { updateSession } from "@/server/supabaseMiddleware";

export async function middleware(request: NextRequest) {
  return await updateSession(request);
}

export const config = {
  matcher: [
    "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
  ],
};

If I use the following in my [user]/layout.tsx:
import { getUserData } from "@/server/auth";

const AppLayout = async ({ params }: { params: { user: string } }) => {
  const user = await getUserData(params.user);
  return <div>{user.user_metadata.name}</div>;
};

export default AppLayout;

and my getUserData:
export const getUserData = async (username: string) => {
  const user = await getUser();
  if (!user) {
    return redirect("/auth");
  }
  if (user.user_metadata.user_name !== username) {
    return redirect(`/${user.user_metadata.user_name}`);
  }
  return user;
};

Would it be well implemented? πŸ€”
I would be protecting and doing the redirect directly from the layout
Avatar
B33fb0n3
your middleware right now only updates the session. Right now, it does not handle the auth process. As I said: If I would be you, I would let my middleware handle the auth process to protect specific routes
Answer
Avatar
Ichneumonid waspOP
Oh ok, I got it. Thank you very much πŸ˜„
Avatar
B33fb0n3
does that information solved your problem? πŸ˜„
Avatar
B33fb0n3
@Ichneumonid wasp ?
Avatar
Ichneumonid waspOP
Hii @B33fb0n3 πŸ˜„

In the end, I managed to solve it using Next.js middleware and looking at a Supabase example on Github. Thank you very much for your help!
Authentication and route protection worked great πŸ₯³
Avatar
B33fb0n3
sure thing. Please mark solution
Avatar
Ichneumonid waspOP
Ready πŸš€
Avatar
B33fb0n3