Next.js Discord

Discord Forum

Best practices for authentication checking

Answered
sergiy.eth posted this in #help-forum
Open in Discord
I am using firebase and using firebase admin api to check for authentication status via cookies.

I am doing this call at the layout.tsx level

import { redirect } from 'next/navigation';

import LoggedIn from '@/components/layouts/logged-in';
import { getCurrentUser } from '@/lib/firebase/firebase-admin';
import InvoicesNav from './invoices-nav';

export const metadata = {
  title: 'Invoices | Acctual',
};

export default async function InvoiceLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const currentUser = await getCurrentUser();

  if (!currentUser) {
    redirect('/login');
  }
  const createInvoiceAction = {
    label: 'Create invoice',
    href: '/invoices/new',
  };

  return (
    <LoggedIn title="Invoices" action={createInvoiceAction}>
      <div className="w-full">
        <InvoicesNav />
        <div className="pt-8 pb-6">{children}</div>
      </div>
    </LoggedIn>
  );
}


export async function getCurrentUser() {
  const session = await getSession();
  if (!(await isUserAuthenticated(session))) {
    return null;
  }

  const decodedIdToken = await auth.verifySessionCookie(session!);
  const currentUser = await auth.getUser(decodedIdToken.uid);
  return currentUser;
}


Is there a more performant way to do this? I have layouts for separate parts of the app that need to be authenticated, but wondering if there's a better way to do this so that it doesn't take long between navigation switches
Answered by B33fb0n3
yea, but it's very hard to maintain everything, when you do the full auth in every function and route. I recommend you doing that in middleware. you can directly use the code, that you have in layout and put it inside your middleware. I am not quite sure, if firebarse works on edge
View full answer

7 Replies

@sergiy.eth I am using firebase and using firebase admin api to check for authentication status via cookies. I am doing this call at the `layout.tsx` level tsx import { redirect } from 'next/navigation'; import LoggedIn from '@/components/layouts/logged-in'; import { getCurrentUser } from '@/lib/firebase/firebase-admin'; import InvoicesNav from './invoices-nav'; export const metadata = { title: 'Invoices | Acctual', }; export default async function InvoiceLayout({ children, }: { children: React.ReactNode; }) { const currentUser = await getCurrentUser(); if (!currentUser) { redirect('/login'); } const createInvoiceAction = { label: 'Create invoice', href: '/invoices/new', }; return ( <LoggedIn title="Invoices" action={createInvoiceAction}> <div className="w-full"> <InvoicesNav /> <div className="pt-8 pb-6">{children}</div> </div> </LoggedIn> ); } ts export async function getCurrentUser() { const session = await getSession(); if (!(await isUserAuthenticated(session))) { return null; } const decodedIdToken = await auth.verifySessionCookie(session!); const currentUser = await auth.getUser(decodedIdToken.uid); return currentUser; } Is there a more performant way to do this? I have layouts for separate parts of the app that need to be authenticated, but wondering if there's a better way to do this so that it doesn't take long between navigation switches
thing is, doing it in the layout is not secure. https://github.com/eric-burel/securing-rsc-layout-leak

Use a middleware, auth inside a page or in a data fetching method.
is there an example of this pattern for firebase anywhere? i feel like middleware is the right approach here, page auth makes sense, at data fetching might make sense too cause im using tanstack query with api routes so each data fetch route may be able to do the check and if it returns 401, the frontend redirects to login, interesting
@sergiy.eth is there an example of this pattern for firebase anywhere? i feel like middleware is the right approach here, page auth makes sense, at data fetching might make sense too cause im using tanstack query with api routes so each data fetch route may be able to do the check and if it returns 401, the frontend redirects to login, interesting
yea, but it's very hard to maintain everything, when you do the full auth in every function and route. I recommend you doing that in middleware. you can directly use the code, that you have in layout and put it inside your middleware. I am not quite sure, if firebarse works on edge
Answer
@sergiy.eth do you need anything else?
@sergiy.eth ?
All good here, thanks!