添加basePath后NextAuth出现CLIENT_FETCH_ERROR及404问题求助
问题现象
- 未配置
basePath时,NextAuth 认证流程正常;添加basePath: '/demand-planning'后,登录页面加载触发错误:
[next-auth][error][CLIENT_FETCH_ERROR] "\nhttps://next-auth.js.org/errors#client_fetch_error" "Unexpected token '<', "<!DOCTYPE "... is not valid JSON" {}
- 注册页及登录操作时控制台持续报错:
[next-auth][error][CLIENT_FETCH_ERROR] "\nhttps://next-auth.js.org/errors#client_fetch_error" "Failed to fetch" {}
- 输入正确凭证登录时返回404错误,尝试修改
.env中NEXTAUTH_URL添加basePath后问题未解决。
核心原因
NextAuth 内部API请求路径未自动适配 basePath,导致请求指向错误地址,返回HTML页面而非预期的JSON数据,最终引发解析失败。
解决步骤
修正
NEXTAUTH_URL配置
在.env文件中,NEXTAUTH_URL必须包含完整的basePath路径:NEXTAUTH_URL=http://localhost:3000/demand-planning调整自定义登录页面路径
NextAuth 的pages.signIn配置需匹配basePath,确保跳转路径正确:pages: { signIn: '/demand-planning/auth/signin', },若需代码灵活性,可通过环境变量动态拼接(需在
.env新增NEXT_PUBLIC_BASE_PATH=/demand-planning):pages: { signIn: `${process.env.NEXT_PUBLIC_BASE_PATH || ''}/auth/signin`, },验证API路由访问路径
NextAuth 的API路由位于app/api/auth/[...nextauth]/route.ts,添加basePath后实际访问路径应为http://localhost:3000/demand-planning/api/auth/[...nextauth],需确保前端请求未指向错误地址。检查NestJS后端跨域配置
由于前端路径变化,需确保后端CORS配置允许包含basePath的请求来源,或直接放行必要的访问域名。
修改后的完整配置示例
.env 文件
NEXTAUTH_URL=http://localhost:3000/demand-planning NEXTAUTH_SECRET=random-secret-key NEXTAUTH_BACKEND_URL=http://localhost:3001 NEXT_PUBLIC_BASE_PATH=/demand-planning
route.ts 文件(关键修改部分)
import NextAuth from 'next-auth' import CredentialsProvider from 'next-auth/providers/credentials' const handler = NextAuth({ providers: [ // 保留原有provider配置 CredentialsProvider({ name: 'credentials', credentials: { username: { label: 'Username', type: 'text' }, password: { label: 'Password', type: 'password' } }, async authorize(credentials) { // 保留原有授权逻辑 } }) ], callbacks: { // 保留原有callbacks配置 async jwt({ token, user }) { if (user) { token.accessToken = user.accessToken token.refreshToken = user.refreshToken token.username = user.username token.department = user.department token.location = user.location token.company = user.company token.roles = user.roles } return token }, async session({ session, token }) { session.accessToken = token.accessToken session.refreshToken = token.refreshToken session.user.username = token.username session.user.department = token.department session.user.location = token.location session.user.company = token.company session.user.roles = token.roles return session } }, pages: { signIn: `${process.env.NEXT_PUBLIC_BASE_PATH || ''}/auth/signin`, }, session: { strategy: 'jwt', }, secret: process.env.NEXTAUTH_SECRET, }) export { handler as GET, handler as POST }
next.config.ts(保留原有配置)
import type { NextConfig } from "next"; const nextConfig: NextConfig = { basePath: '/demand-planning', trailingSlash: true, }; export default nextConfig;
内容的提问来源于stack exchange,提问作者Abdul Rahuman

