Next.js使用NextAuth保护路由时API请求报错求助
问题解决:NextAuth中间件引发API请求JSON解析错误
问题背景
用NextAuth保护Next.js站点所有路由,仅允许未认证用户访问/auth/login页面。编写中间件排除了静态资源和/api/auth路径,但页面在getServerSideProps中调用自定义API路由时,出现FetchError——提示JSON响应无效,原因是未认证的API请求被中间件重定向到登录页,返回HTML而非JSON格式内容。
错误原因
当前中间件仅排除了/api/auth路径,所有其他自定义API路由仍会被拦截。当未认证用户的页面发起API请求时,中间件将请求重定向到登录页,返回的HTML内容与前端期望的JSON格式不匹配,从而触发解析错误。
修复方案
调整中间件逻辑,区分页面路由和API路由的处理规则:
- 排除所有
/api开头的路径(或按需配置公开API),避免API请求被重定向 - 对API路由返回
401 Unauthorized状态码(更符合API交互逻辑),而非重定向到登录页
修改后的中间件代码
// middleware.js import { NextResponse } from 'next/server'; import { getToken } from 'next-auth/jwt' export default async function middleware(req) { // 排除静态资源路径 if (req.nextUrl.pathname.startsWith('/_next/') || req.nextUrl.pathname.startsWith('/icons/') || req.nextUrl.pathname.startsWith('/fonts/')) { return; } // 处理API路由:未认证则返回401,而非重定向 if (req.nextUrl.pathname.startsWith('/api/')) { const session = await getToken({ req }) if (!session) { return new NextResponse(JSON.stringify({ error: 'Unauthorized' }), { status: 401, headers: { 'Content-Type': 'application/json' } }) } return; } // 获取用户会话 const session = await getToken({ req }) // 已登录用户访问登录页时,重定向到首页 if (req.nextUrl.pathname.startsWith('/auth/login')) { if (session) { const url = req.nextUrl.clone() url.pathname = '/' return NextResponse.redirect(url) } } // 未登录用户访问非登录页时,重定向到登录页 if (!req.nextUrl.pathname.startsWith('/auth/login') && !session) { const url = req.nextUrl.clone() url.pathname = '/auth/login' return NextResponse.redirect(url) } }
补充说明
- 若有部分自定义API需要公开访问,可单独添加排除规则,例如:
if (req.nextUrl.pathname.startsWith('/api/public/')) { return; } - 前端可在
getServerSideProps中捕获API返回的401错误,再执行页面重定向,既符合API规范,又能实现路由保护。
内容的提问来源于stack exchange,提问作者Rawand
相关产品推荐
相关产品推荐

