NextJS配置basePath后NextAuth请求忽略路径致404的问题求助
NextAuth 配合 Next.js basePath 登录请求404问题解决
问题现象
将Next.js应用从根路径切换到带basePath的配置后,提交登录表单时,请求会调用http://localhost:3000/api/auth/providers并返回404(请求忽略了basePath),随后被重定向到http://localhost:3000/api/auth/error。尝试拦截请求修改URL但代码未执行。
相关配置代码
next.config.js 文件
/** @type {import('next').NextConfig} */ const basePath = process.env.NEXT_PUBLIC_BASE_PATH; const nextConfig = { reactStrictMode: true, swcMinify: true, basePath: `${basePath}`, assetPrefix: `${basePath}/`, experimental: { appDir: true, }, } module.exports = nextConfig
.env.local 文件
NEXTAUTH_URL=http://localhost:3000/myapp/api/auth NEXT_PUBLIC_API_URL=http://localhost:8000/backend/ NEXT_PUBLIC_TOKEN_REFRESH_LIMIT=120 NEXT_PUBLIC_BASE_PATH=/myapp NEXT_PUBLIC_SESSION_BASE_PATH=/myapp/api/auth NEXTAUTH_DEBUG=true NEXTAUTH_BASE_PATH=/myapp
LoginForm 组件
"use client" import React from 'react' import { signIn } from "next-auth/react"; const LoginForm = () => { const basePath = process.env.NEXT_PUBLIC_BASE_PATH; const baseUrlCallback = async (baseUrl: string) => { const modifiedUrl = `${baseUrl}${basePath}`; console.log("modify URL", modifiedUrl) return modifiedUrl; }; const handleSubmit = async (e) => { e.preventDefault(); console.log("Login FORM has basePath",basePath) const username = e.target.username.value; const password = e.target.password.value; username.length > 0 && await signIn("credentials", { baseUrl: baseUrlCallback, username: username, password: password, redirect: true, callbackUrl: "/myapp/dashboard", }); }; return ( <form onSubmit={handleSubmit} action="myapp/api/auth/callback/credentials"> <label className="form-group has-float-label mb-4"> <input className="form-control" id="username" type="text"/> <span>Username</span> </label> <label className="form-group has-float-label mb-4"> <input className="form-control" type="password" id="password" /> <span>Password</span> </label> <div className="d-flex justify-content-between align-items-center"> <a href="#">Forgot your password?</a> <button className="btn btn-primary btn-lg btn-shadow" type="submit">LOGIN</button> </div> </form> ) } export default LoginForm
未执行的拦截代码
const handler: NextApiHandler = (req: NextApiRequest, res: NextApiResponse) => { const basePath = process.env.NEXT_PUBLIC_BASE_PATH; const originalUrl = req.url; req.url = `${basePath}${originalUrl}`; console.log("INTERCEPT NEXT AUTH:", req.url, originalUrl) return NextAuth(req, res, authOptions); }; export { handler as GET, handler as POST }
解决步骤
1. 给NextAuth配置添加basePath参数
在你的NextAuth配置文件(通常是app/api/auth/[...nextauth]/route.ts或pages/api/auth/[...nextauth].ts)中,明确指定basePath:
export const authOptions: AuthOptions = { // 其他现有配置... basePath: process.env.NEXT_PUBLIC_BASE_PATH, };
这是核心修复点,NextAuth需要通过该参数识别应用的basePath,才能生成正确的API请求路径。
2. 调整环境变量与next.config.js
- 保持
.env.local中NEXTAUTH_URL和NEXTAUTH_BASE_PATH的正确性:NEXTAUTH_BASE_PATH仅需要填写应用的basePath(如/myapp),无需包含/api/auth。 - 修改
next.config.js中的assetPrefix,去掉末尾的斜杠:assetPrefix: basePath, // 原代码为`${basePath}/`,移除末尾/
3. 简化LoginForm的signIn调用
- 移除无效的
baseUrlCallback,直接在signIn参数中指定basePath:await signIn("credentials", { basePath: process.env.NEXT_PUBLIC_BASE_PATH, username: username, password: password, redirect: true, callbackUrl: `${process.env.NEXT_PUBLIC_BASE_PATH}/dashboard`, }); - 删除form标签上的
action属性,避免与handleSubmit的逻辑冲突:<form onSubmit={handleSubmit}> // 表单内容... </form>
4. 删除无效的请求拦截代码
该拦截代码未执行是因为NextAuth的路由处理优先级更高,且正确配置basePath后无需此类hack方式,直接删除即可。
5. 验证修复效果
重启Next.js开发服务器,打开浏览器控制台查看登录请求,确认请求路径变为http://localhost:3000/myapp/api/auth/providers,测试登录流程是否正常。
内容的提问来源于stack exchange,提问作者Kartzallis
相关产品推荐
相关产品推荐

