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

Next-Auth遇JWEDecryptionFailed错误,服务端组件获取Token为null

解决NextAuth中JWEDecryptionFailed解密失败及Token为null的问题

问题详情

在服务端组件中获取Token时返回null,排查发现以下错误:

[next-auth][error][JWT_SESSION_ERROR] 
decryption operation failed {
  message: 'decryption operation failed',
  stack: 'JWEDecryptionFailed: decryption operation failed\n' +
    '    at gcmDecrypt (webpack-internal:///(rsc)/./node_modules/jose/dist/node/cjs/runtime/decrypt.js:68:15)\n' +
    '    at decrypt (webpack-internal:///(rsc)/./node_modules/jose/dist/node/cjs/runtime/decrypt.js:91:20)\n' + 
    '    at flattenedDecrypt (webpack-internal:///(rsc)/./node_modules/jose/dist/node/cjs/jwe/flattened/decrypt.js:137:52)\n' +
    '    at async compactDecrypt (webpack-internal:///(rsc)/./node_modules/jose/dist/node/cjs/jwe/compact/decrypt.js:20:23)\n' +
    '    at async jwtDecrypt (webpack-internal:///(rsc)/./node_modules/jose/dist/node/cjs/jwt/decrypt.js:10:23)\n' +
    '    at async Object.decode (webpack-internal:///(rsc)/./node_modules/next-auth/jwt/index.js:44:25)\n' +    
    '    at async Object.session (webpack-internal:///(rsc)/./node_modules/next-auth/core/routes/session.js:25:34)\n' +
    '    at async AuthHandler (webpack-internal:///(rsc)/./node_modules/next-auth/core/index.js:161:37)\n' +    
    '    at async NextAuthRouteHandler (webpack-internal:///(rsc)/./node_modules/next-auth/next/index.js:50:30)\n' +
    '    at async NextAuth._args$ (webpack-internal:///(rsc)/./node_modules/next-auth/next/index.js:85:24)\n' + 
    '    at async C:\Users\Rax\Desktop\zurii-hr-panel\node_modules\next\dist\compiled\next-server\app-route.runtime.dev.js:1:66877',
  name: 'JWEDecryptionFailed'
}

对应的NextAuth配置代码(options.ts):

// https://www.youtube.com/watch?v=w2h54xz6Ndw&t=1721s

import type { NextAuthOptions } from 'next-auth'
import GoogleProvider from "next-auth/providers/google"
import AppleProvider from "next-auth/providers/apple"
import CredentialsProvider from 'next-auth/providers/credentials'
import NextAuth from 'next-auth/next';

import loginService from "@/services/auth";

export const options: NextAuthOptions = {
    secret: "123",
    providers: [
        CredentialsProvider({
            name: "Credentials",
            credentials: {
                email: {
                    label: "Email",
                    type: "email",
                    placeholder: "Email"
                },
                password: {
                    label: "Password:",
                    type: "password",
                    placeholder: "Password"
                }
            },
            async authorize(credentials) {
                // This is where you need to retrieve user data 
                // to verify with credentials
                // Docs: https://next-auth.js.org/configuration/providers/credentials
                const email = credentials?.email || "";
                const password = credentials?.password || "";

                let user = await loginService.login(email, password);
                // modify object
                user = {
                    token: user.access_token
                }

                if (user && user.token) {
                    return user;
                } else {
                    return null;
                }
            }
        })
    ],
    session: {
        strategy: "jwt",
    },
    callbacks: {
        async jwt({ token, user }) {
            return { ...token, ...user };
        },

        async session({ session, token }) {
            session.user = token as any;
            return session;
        },
    },
    pages: {
       signIn: "/login" 
    }
};

添加secret后问题仍未解决。

问题原因

  1. Secret长度不满足加密要求:你使用的secret: "123"长度过短,NextAuth依赖的jose库要求JWE解密密钥至少为32字节(256位),短密钥会直接导致解密失败。
  2. 旧Session缓存干扰:浏览器中可能缓存了之前用无效secret生成的Session Cookie,即使更新了secret,旧Cookie无法解密仍会抛出错误。

解决方案

1. 生成符合要求的安全Secret

执行以下Node.js命令生成32字节的十六进制密钥:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

将生成的字符串替换配置中的secret: "123",同时确保该值与环境变量NEXTAUTH_SECRET保持一致(如果项目中使用环境变量管理配置)。

2. 清除浏览器缓存与Cookie

手动清除当前站点的所有Cookie,或使用浏览器隐私模式测试,避免旧的无效Session影响解密流程。

3. 验证用户数据返回逻辑

在authorize方法中添加日志,确认登录接口返回的access_token有效,且传递给NextAuth的user结构正确:

async authorize(credentials) {
    const email = credentials?.email || "";
    const password = credentials?.password || "";

    let user = await loginService.login(email, password);
    console.log('登录接口返回数据:', user); // 确认access_token存在
    user = {
        token: user.access_token
    }
    console.log('传递给NextAuth的用户数据:', user);

    if (user && user.token) {
        return user;
    } else {
        return null;
    }
}

4. 确保服务端组件获取Session的方式正确

在服务端组件中必须使用getServerSession方法获取Session,示例代码:

import { getServerSession } from "next-auth/next"
import { options } from "@/app/api/auth/[...nextauth]/options"

export default async function YourServerComponent() {
    const session = await getServerSession(options)
    if (session) {
        console.log('获取到的Token:', session.user.token)
    }
    // 其他业务逻辑
}

内容的提问来源于stack exchange,提问作者La Bola Al Riel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:49:58