You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中间件中无法删除Cookie的问题排查

Next.js中间件无法删除过期Token的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。

解决方案

  1. 创建NextResponse.redirect实例,而非直接返回重定向响应;
  2. 通过response.cookies.delete()方法删除指定Cookie,需确保参数与设置Cookie时的属性(如path、domain、secure)完全一致;
  3. 若需兼容旧版浏览器,也可通过设置过期时间为过去的日期来清除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:07:45