nextauthjs / next-auth

Authentication for the Web.
https://authjs.dev
ISC License
24.95k stars 3.52k forks source link

Next JS 15 Cookie Error with Auth JS v5 #12220

Closed Michahide closed 1 day ago

Michahide commented 6 days ago

Environment

  System:
    OS: Windows 11 10.0.22631
    CPU: (16) x64 13th Gen Intel(R) Core(TM) i7-13620H
    Memory: 3.14 GB / 15.70 GB
  Binaries:
    Node: 22.11.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.9.0 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.12.3 - ~\AppData\Local\pnpm\pnpm.EXE
  Browsers:
    Edge: Chromium (130.0.2849.68)
    Internet Explorer: 11.0.22621.3527
  npmPackages:
    next: ^15.0.3 => 15.0.3
    next-auth: 5.0.0-beta.25 => 5.0.0-beta.25
    react: 19.0.0-rc-66855b96-20241106 => 19.0.0-rc-66855b96-20241106

Reproduction URL

https://github.com/Michahide/legendary-octo-goggles.git

Describe the issue

When token is expired or the session is null and when the app want to automatically sign in again, the app show this error [ Server ] Error: Cookies can only be modified in a Server Action or Route Handler. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#options

How to reproduce

use the session and signIn function in page.tsx like this

export default function Page() {
const session = await auth() if (!session) { await signIn("keycloak") // Force sign in to obtain a new set of access and refresh tokens } }

Expected behavior

use the session and signIn function in page.tsx like this

export default function Page() {
const session = await auth() if (!session) { await signIn("keycloak") // Force sign in to obtain a new set of access and refresh tokens } }

user would be redirected to login page

VovaGayduk42 commented 3 days ago

Hi I had a same problem I suppose next server component doesn't have access to cookie In this conditional I return a client component that have access to cookie

But I really don't like this solution Mayby next-auth developers will suggest other

apps/web/app/(authorized)/layout.tsx

import React from "react";

import { AuthorizedLayout } from "widgets/authorized-layout";
import { SignIn } from "entities/user/sign-in";

import { auth } from "../../auth";

export default async function Authorized(props: React.PropsWithChildren) {
    const session = await auth();

    if (!session?.user?.name || session?.error) {
        return <SignIn />;
    }

    return <AuthorizedLayout>{props.children}</AuthorizedLayout>;
}

sign-in.tsx

"use client";

import { signIn } from "next-auth/react";

export function SignIn() {
    if (typeof window !== "undefined") {
        signIn("keycloak");
    }

    return null;
}
balazsorban44 commented 1 day ago

Hi, this is expected behavior, and not a bug in NextAuth.js, as per the Next.js documentation the error message links you to.

See also: https://nextjs.org/docs/app/api-reference/functions/cookies#setting-a-cookie

The signIn() action requires setting security cookies for the sign-in flow (callback urls, state, etc.), which is not possible during a Server Component render.

You can use the proposed method from https://github.com/nextauthjs/next-auth/issues/12220#issuecomment-2475583199 for example.

Note: For awareness, for security and privacy reasons, in some cases, it is problematic to sign a user into a website without their consent, ie. they should click on some button to acknowledge they will be logged in instead.