You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 14 + Next-Auth出现Session cookie超4096字节错误求解决

Next.js 14升级后Next-Auth Session Cookie过大问题解决

问题描述

此前使用Next.js 13.x.x版本时Next-Auth认证功能正常,升级至Next.js 14.x.x后,终端控制台报错:Session cookie exceeds allowed 4096 bytes.,认证功能异常。

相关代码如下:

authOptions 完整代码

import { AuthOptions } from "next-auth";
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import prisma from "./prisma";
import CredentialsProvider from "next-auth/providers/credentials";
import bcrypt from "bcrypt";

export const authOptions: AuthOptions = {
    adapter: PrismaAdapter(prisma),
    providers: [
        CredentialsProvider({
            credentials: {
                email: { label: 'email', type: 'text' },
                password: { label: 'password', type: 'password' },
            },

            authorize: async (credential) => {
                if (!credential?.email || !credential?.password) {
                    throw new Error("Invalid email or password");
                }

                const user = await prisma.user.findUnique({
                    where: { email: credential.email },
                    include: {
                        histories: true,
                        resto: true,
                    }
                });

                if (!user || !user?.password) {
                    throw new Error("Email does not match any user...");
                }

                const isCorrect = await bcrypt.compare(credential.password, user.password)
                if (!isCorrect) {
                    throw new Error("Password salah euy")
                }

                return {
                    ...user,
                    id: user.id.toString(),
                    name: user.name,
                    role: user.role,
                };
            },
        })
    ],
    callbacks: {
        jwt: async ({ token, user, session, trigger }) => {
            if (trigger === 'update') {
                return {
                    ...token,
                    ...session.user
                }
            }

            if (user) {
                const userRelation = await prisma.user.findUnique({
                    where: { id: Number(user.id) },
                    include: {
                        histories: true,
                        resto: true,
                    }
                });

                if (!userRelation) {
                    throw new Error("User not found");
                }

                return {
                    ...token,
                    // id: user.id,
                    ...userRelation
                };
            }

            if (token.name !== null && token.name !== undefined) {
                await prisma.user.update({
                    where: { id: Number(token.id) },
                    data: { name: token.name }
                });
            }

            return token;
        },
        session: async ({ session, token, user }) => {
            const newSession = {
                ...session,
                user: {
                    ...session.user,
                    id: token.id,
                    name: token.name,
                    role: token.role,
                }
            }

            return newSession;
        },
    },
    pages: {
        signIn: '/',
        error: '/',
    },
    debug: true,
    session: { strategy: "jwt" },
    secret: "rahasia",
}

route.ts 调用代码

import { authOptions } from '@/lib/auth';
import NextAuth from 'next-auth';

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST }

next-auth.d.ts 类型声明

import NextAuth from "next-auth";

declare module "next-auth" {
  interface Session {
    user: {
      id: string;
      name: string;
      email: string;
      role: string;
      [key: string]: string;
    };
  }
}

解决方案

不需要降级回Next.js 13,问题核心是JWT中存储了大量冗余数据,导致Cookie体积超过浏览器允许的4096字节限制。

1. 移除JWT中的冗余关联数据

你的代码在authorize方法和jwt回调中,都查询并存储了用户的histories和resto关联对象,但session回调只用到了id、name、role等基础字段,这些关联数据完全没必要放进JWT。

修改authorize方法

移除关联查询,只获取用户基础信息:

const user = await prisma.user.findUnique({
    where: { email: credential.email },
    // 删除include字段,不再查询histories和resto
});

修改jwt回调的用户登录逻辑

不再重复查询关联数据,只合并必要字段到token:

if (user) {
    return {
        ...token,
        id: user.id.toString(),
        name: user.name,
        email: user.email,
        role: user.role
    };
}

2. 迁移JWT回调中的数据库操作

jwt回调里的用户名称更新逻辑,应该移到独立的API路由中处理,不要在JWT回调里执行数据库操作——这会增加回调执行时间,还可能导致token不必要的更新膨胀。

3. 验证修复效果

修改完成后,保持debug: true重新测试,终端不再出现Cookie超标的报错即为修复成功。如果问题仍存在,检查是否有其他冗余字段被意外加入JWT,确保只保留session所需的必要数据。

内容的提问来源于stack exchange,提问作者Terhebat Hokage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:45:42