lucia-auth / lucia

Authentication, simple and clean
https://lucia-auth.com
MIT License
8.32k stars 447 forks source link

[Bug]: Error: × You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. #1587

Closed Qodestackr closed 1 month ago

Qodestackr commented 1 month ago

Package

lucia

Describe the bug

Code:

import { cookies } from "next/headers";
import { cache } from "react";

import type { Session, User } from "lucia";
import { lucia } from "@/lib/lucia";

export const getAuth = cache(
  async (): Promise<
    { user: User; session: Session } | { user: null; session: null }
  > => {
    const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null;
    if (!sessionId) {
      return {
        user: null,
        session: null,
      };
    }

    const result = await lucia.validateSession(sessionId);

    try {
      if (result.session && result.session.fresh) {
        const sessionCookie = lucia.createSessionCookie(result.session.id);
        cookies().set(
          sessionCookie.name,
          sessionCookie.value,
          sessionCookie.attributes,
        );
      }
      if (!result.session) {
        const sessionCookie = lucia.createBlankSessionCookie();
        cookies().set(
          sessionCookie.name,
          sessionCookie.value,
          sessionCookie.attributes,
        );
      }
    } catch {}
    return result;
  },
);

USED HERE:


"use client";

import { usePathname } from 'next/navigation';

import DashboardHeader from "@/components/layout/header";
import Sidebar from "@/components/layout/sidebar";
import { redirect } from 'next/navigation';

// Dummy getAuth function for debugging purposes
async function getAuth() {
  return { user: null };
}

]export default async function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const pathname = usePathname();
  const hideNavbar = pathname === '/dashboard/meet';
  const hideNavbarOnLab = pathname === '/dashboard/lab';

  const { user } = await getAuth();

  if (!user) {
    redirect('/auth/login');
  }

  return (
    <div suppressHydrationWarning={true}>
      {hideNavbar ? null : <DashboardHeader />}
      <div className="flex h-screen dark:bg-black dark:text-gray-50 border-collapse overflow-hidden">
        <Sidebar />
        <main className="pt-8 pb-8 px-4 sm:px-8 container">{children}</main>
      </div>
    </div>
  );
}
Qodestackr commented 1 month ago

Also related to: Error: PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in unknown).

pilcrowOnPaper commented 1 month ago

Well, it looks like you're importing server-only code into a client component. Really doubt it's an issue with Lucia

Qodestackr commented 1 month ago

Yes its not but please. I fixed that but dont know if I need to be accessing sessions in client components. @pilcrowOnPaper

pilcrowOnPaper commented 1 month ago

You probably don't need to access the token on the client. You could probably pass the expiration data as a prop if you need it