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

NextJS14 App Router下NextAuth中间件页面保护问题求助

问题解决方案与可用示例

一、解决oidc-token-hash模块错误

这个错误核心原因是中间件运行在Edge Runtime环境下,而getServerSession是为Node.js Runtime设计的,无法在中间件中调用,同时可能伴随依赖版本兼容问题。

修复步骤:

  1. 升级NextAuth及核心依赖到最新版本:
    npm update next-auth @auth/core
    
  2. 彻底移除中间件中getServerSession的导入和调用,改用NextAuth中间件内置的会话获取方式。

二、修复中间件无法识别有效会话的问题

核心问题:未向withAuth传递authOptions配置

你的原代码中withAuth没有关联认证配置,导致中间件无法验证会话有效性。以下是两种可用的正确写法:

写法1:带自定义逻辑的中间件

import { withAuth } from "next-auth/middleware";
import authOptions from './app/api/auth/[...nextauth]/authOptions';

export default withAuth(
  function middleware(req) {
    // 直接通过req.nextauth获取会话信息
    console.log("会话Token:", req.nextauth.token);
  },
  {
    // 必须传递authOptions,让中间件知晓认证规则
    authOptions: authOptions,
    callbacks: {
      authorized: ({ token }) => {
        console.log("授权校验Token:", token);
        // 简单校验:存在Token则允许访问
        return !!token;
      },
    },
  }
);

// 配置需要保护的路由规则
export const config = { matcher: ["/creator/:path*"] };

写法2:极简路由保护(无自定义逻辑)

如果仅需要保护路由,不需要额外中间件逻辑,可直接使用:

import NextAuth from "next-auth";
import authOptions from './app/api/auth/[...nextauth]/authOptions';

export default NextAuth(authOptions).auth;

export const config = { matcher: ["/creator/:path*"] };

三、优化Cognito认证配置

确保Cognito Provider配置完整且正确,以下是优化后的authOptions示例:

import type { NextAuthOptions } from 'next-auth';
import Cognito from "next-auth/providers/cognito";

const authOptions: NextAuthOptions = {
  providers: [
    Cognito({
      clientId: process.env.COGNITO_CLIENT_ID!,
      clientSecret: process.env.COGNITO_CLIENT_SECRET!,
      // 确保issuer是完整的Cognito用户池URL,格式:https://cognito-idp.<区域>.amazonaws.com/<用户池ID>
      issuer: process.env.COGNITO_ISSUER!,
      // 显式声明需要获取的用户信息范围
      scope: "openid email profile",
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
  // 开发环境开启debug模式,便于排查认证日志
  debug: process.env.NODE_ENV === "development",
  callbacks: {
    async jwt({ token, account, profile }) {
      // 首次登录时保存Cognito的访问令牌(若需调用Cognito API)
      if (account) {
        token.accessToken = account.access_token;
        token.expiresAt = account.expires_at;
      }
      // 持久化Cognito用户唯一标识sub
      if (profile) {
        token.sub = profile.sub;
      }
      return token;
    },
    async session({ session, token }) {
      // 将Token中的字段同步到Session,方便前端/服务端使用
      session.user.sub = token.sub;
      session.accessToken = token.accessToken;
      return session;
    },
  },
  // 自定义会话Cookie配置(生产环境确保secure为true)
  cookies: {
    sessionToken: {
      name: process.env.NODE_ENV === "production" 
        ? "__Secure-next-auth.session-token" 
        : "next-auth.session-token",
      options: {
        httpOnly: true,
        sameSite: "lax",
        path: "/",
        secure: process.env.NODE_ENV === "production",
      },
    },
  },
};

export default authOptions;

四、额外排查步骤

  1. 确认NEXTAUTH_SECRET环境变量已设置,且长度不小于32字符。
  2. 检查AWS Cognito控制台中,回调URL已添加http://localhost:3000/api/auth/callback/cognito(开发环境)或生产环境域名对应的回调地址。
  3. 查看浏览器Cookie,确认存在next-auth.session-token或__Secure-next-auth.session-token,且路径为/。

内容的提问来源于stack exchange,提问作者Eric Bloch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 13:07:52