Next.js中间件中无法删除Cookie的问题排查
我正在开发一个Next.js应用,使用中间件检查用户的token是否过期。若token过期,我希望清除并删除Cookie,同时将用户重定向至登录页面。但request.cookies.delete('token')这一行并未按预期移除Cookie——代码能正确识别token过期并触发登录重定向,但Cookie删除操作不生效,用户仍能访问受限页面。相关代码如下:
export async function middleware(request: NextRequest) { const path = request.nextUrl.pathname; const token = request.cookies.get('token')?.value || ''; const url = `${process.env.NEXT_PUBLIC_BASE_URL}users/auth/check-token-expiration`; let tokenExpirationData; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ token, }), }); if (response.ok) { tokenExpirationData = await response.json(); console.log(tokenExpirationData?.data); } else { console.error('Error occurred while fetching data:', response.statusText); } } catch (error) { console.error('Error occurred:', error); } if (path !== '/login' && tokenExpirationData && tokenExpirationData.data) { request.cookies.clear(); request.cookies.delete('token'); // 这行未生效 return NextResponse.redirect(new URL('/login', request.nextUrl)); } }
问题原因
你操作的request.cookies只是当前请求携带的Cookie副本,属于只读的请求快照,修改它不会对浏览器端实际存储的Cookie产生任何影响。Next.js中间件中要修改或删除Cookie,必须通过NextResponse对象设置响应头,才能通知浏览器更新Cookie。
解决方案
- 创建
NextResponse.redirect实例,而非直接返回重定向响应; - 通过
response.cookies.delete()方法删除指定Cookie,需确保参数与设置Cookie时的属性(如path、domain、secure)完全一致; - 若需兼容旧版浏览器,也可通过设置过期时间为过去的日期来清除Cookie。
修正后的代码示例
export async function middleware(request: NextRequest) { const path = request.nextUrl.pathname; const token = request.cookies.get('token')?.value || ''; const url = `${process.env.NEXT_PUBLIC_BASE_URL}users/auth/check-token-expiration`; let tokenExpirationData; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ token, }), }); if (response.ok) { tokenExpirationData = await response.json(); console.log(tokenExpirationData?.data); } else { console.error('Error occurred while fetching data:', response.statusText); } } catch (error) { console.error('Error occurred:', error); } if (path !== '/login' && tokenExpirationData && tokenExpirationData.data) { // 创建重定向响应对象 const loginUrl = new URL('/login', request.nextUrl); const response = NextResponse.redirect(loginUrl); // 删除token Cookie,需匹配设置时的属性 response.cookies.delete('token', { path: '/', // 默认路径为'/',若设置了其他路径需对应修改 // 若设置了domain或secure,需同步添加 // domain: 'your-domain.com', // secure: process.env.NODE_ENV === 'production', // httpOnly: true, // 若设置了httpOnly也需带上 }); // 兼容旧版浏览器的清除方式(可选) // response.cookies.set('token', '', { // path: '/', // expires: new Date(0), // httpOnly: true, // secure: process.env.NODE_ENV === 'production', // }); return response; } // 无需重定向时,继续处理请求 return NextResponse.next(); }
关键注意事项
- 必须操作
NextResponse的cookies对象,而非request的——request.cookies仅用于读取请求中的Cookie,无法修改浏览器存储; - 删除Cookie时,
path、domain等属性必须与当初设置Cookie时完全一致,否则浏览器会判定为不同Cookie,无法删除; - 生产环境中若使用了
secure或httpOnly属性,删除时务必同步带上这些参数。
内容的提问来源于stack exchange,提问作者kristina malozh
相关产品推荐
相关产品推荐

