Next.js 13中JWT认证出现Cannot read properties of undefined (reading 'headers')错误
Next.js 13 + Redux Toolkit + Django JWT认证登录问题排查与解决
问题背景
使用Next.js 13结合Redux Toolkit开发JWT认证系统,后端为Django。登录时前端Redux调用Next.js API路由后出现异常:
- auth.js中弹出提示
Response is [object Response] - 控制台报错:
error TypeError: Cannot read properties of undefined (reading 'headers')
错误根源分析
API路由代码核心问题
- 未导入必要模块:代码直接使用
NextResponse和cookie但未导入,导致NextResponse为undefined,调用setHeader时触发Cannot read properties of undefined (reading 'headers')错误。 - NextResponse用法错误:不能直接调用
NextResponse.setHeader静态方法,需先创建Response实例再操作头信息。 - Set-Cookie数组包含无效元素:数组中混入
console.log语句,会导致Cookie设置失败。 - 缺少异常分支处理:未处理Django返回非200状态的情况,且catch块无响应返回,导致前端接收到异常响应。
auth.js的小问题
alert(\Response is ${res}`)直接将Response对象转为字符串,所以显示[object Response]`,这是正常的对象转字符串行为,但核心问题还是API路由的错误导致响应异常。
修复步骤
1. 修复Next.js API路由代码
导入必要模块,修正Response头设置逻辑,完善错误处理:
import { NextResponse } from 'next/server'; import cookie from 'cookie'; export async function POST(request) { const body = await request.json(); const { email, password } = body; const bodystring = JSON.stringify({ email, password }); try { const apiRes = await fetch(`${API_URL}/api/token/`, { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: bodystring }); const data = await apiRes.json(); if (apiRes.status === 200) { console.log("Login Successful"); // 创建NextResponse实例 const response = NextResponse.json({ success: 'Logged in successfully', status: 200, }); // 设置Cookie response.headers.set('Set-Cookie', [ cookie.serialize( 'access', data.access, { httpOnly: true, secure: process.env.NODE_ENV === 'production', // 生产环境开启secure maxAge: 60 * 30, sameSite: 'strict', path: '/' // 调整path为根路径,避免仅/api/下可用 } ), cookie.serialize( 'refresh', data.refresh, { httpOnly: true, secure: process.env.NODE_ENV === 'production', maxAge: 60 * 60 * 24, sameSite: 'strict', path: '/' } ) ]); console.log("Access and Refresh tokens set successfully"); return response; } else { // 处理Django返回的错误 return NextResponse.json({ error: data.detail || 'Login failed', status: apiRes.status }, { status: apiRes.status }); } } catch (error) { console.error("Login API error:", error); return NextResponse.json({ error: 'Server error', status: 500 }, { status: 500 }); } }
2. 优化auth.js代码
修正提示信息,完善错误处理:
export const login = (email, password) => async dispatch => { const body = JSON.stringify({ email, password }); dispatch({ type: SET_AUTH_LOADING }); try { const res = await fetch('/auth/login/api', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: body }); const data = await res.json(); // 解析响应数据 alert(`Response status: ${res.status}`); if (res.ok) { alert("Login Successful"); dispatch({ type: LOGIN_SUCCESS }); dispatch(load_user()); } else { alert(`Login Failed: ${data.error || 'Unknown error'}`); dispatch({ type: LOGIN_FAIL }); } } catch (error) { alert(`Login Error: ${error.message}`); dispatch({ type: LOGIN_FAIL }); } dispatch({ type: REMOVE_AUTH_LOADING }); }
额外说明
- Cookie的
secure属性建议在生产环境开启,通过process.env.NODE_ENV判断更安全。 - 调整Cookie的
path为/,确保在整个应用内都能携带Cookie,避免后续API请求无法获取Token。 - 前端解析响应数据后,可以更精准地显示错误信息,提升用户体验。
内容的提问来源于stack exchange,提问作者victor
相关产品推荐
相关产品推荐

