NextJS14 App Router下NextAuth中间件页面保护问题求助
问题解决方案与可用示例
一、解决oidc-token-hash模块错误
这个错误核心原因是中间件运行在Edge Runtime环境下,而getServerSession是为Node.js Runtime设计的,无法在中间件中调用,同时可能伴随依赖版本兼容问题。
修复步骤:
- 升级NextAuth及核心依赖到最新版本:
npm update next-auth @auth/core - 彻底移除中间件中
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;
四、额外排查步骤
- 确认
NEXTAUTH_SECRET环境变量已设置,且长度不小于32字符。 - 检查AWS Cognito控制台中,回调URL已添加
http://localhost:3000/api/auth/callback/cognito(开发环境)或生产环境域名对应的回调地址。 - 查看浏览器Cookie,确认存在
next-auth.session-token或__Secure-next-auth.session-token,且路径为/。
内容的提问来源于stack exchange,提问作者Eric Bloch
相关产品推荐
相关产品推荐

