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

NextJS + Express环境下Set Cookie失效问题求助

问题:Express设置Cookie在NextJS前端失效,Postman测试正常

我尝试通过Express后端的response.setHeader方法向NextJS前端设置Cookie,但功能失效:前端能接收JSON响应,却未设置Cookie;但用Postman测试时Cookie可正常设置。使用版本:NextJS 13.0.2、Express 4.18.2、cookie 0.5.0。

服务端代码(Express)

export const loginUser = async (req: Request, res: Response) => {
  const { email, password } = req.body;

  // 清除旧cookie
  res.clearCookie("accessToken", { httpOnly: true });

  if (email !== "" && password !== "") {
    try {
      const foundUser: any = await prisma.users.findFirst({
        where: {
          email,
          password,
        },
      });

      try {
        const accessToken = jwt.sign(
          { id: foundUser.id, email },
          "dspaojdspoadsaodksa",
          {
            expiresIn: "10s",
          }
        );
        const refreshToken = jwt.sign(
          { id: foundUser.id, email },
          "dsaoindsadmnsaosda",
          {
            expiresIn: "50s",
          }
        );

        const savedRefresh = await prisma.refresh_token.upsert({
          where: {
            users_id: foundUser.id,
          },
          update: {
            access_token: accessToken,
            refresh_tk: refreshToken,
            users_id: foundUser.id,
          },
          create: {
            access_expires_in: "",
            refresh_expires_in: "",
            access_token: accessToken,
            refresh_tk: refreshToken,
            users_id: foundUser.id,
          },
        });

        res.setHeader(
          "Set-Cookie",
          cookie.serialize("accessToken", accessToken, {
            maxAge: 1000 * 60 * 15, // 15分钟
            httpOnly: true, // Cookie仅能被服务端访问
          })
        );

        res.json({ accessToken, user: { email }, ok: true });
      } catch (error) {
        console.log("refresh cant be created");
        res.send({ message: "refresh cant be created" });
      }
    } catch (error) {
      res.send({ message: "user not found" });
    }
  } else {
    res.json({ message: "token creation failed" });
  }
};

前端代码(NextJS)

const handleLogin = async (event: React.SyntheticEvent) => {
    event.preventDefault();

    const email = (event?.target as any).email.value;
    const password = (event?.target as any).password.value;

    if (email === "" || password === "") {
      setError(true);
      return;
    }

    const data = {
      email,
      password,
    };

    const resp = await fetch("http://localhost:5000/login", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data),
    });

    const userData = await resp.json();
    console.log(userData);
  };

问题原因与解决方案

这是跨域请求下的Cookie配置问题:Postman默认自动处理Cookie,但浏览器的fetchAPI默认不会在跨域请求中携带或接收Cookie,需要同时在服务端和前端做配置。

1. 服务端(Express)修改

步骤1:配置CORS中间件

先安装cors依赖:

npm install cors

在Express应用中添加CORS配置,允许指定前端Origin并开启Cookie支持:

import cors from 'cors';

// 替换为你的NextJS前端地址,比如http://localhost:3000
const FRONTEND_ORIGIN = 'http://localhost:3000';

app.use(cors({
  origin: FRONTEND_ORIGIN,
  credentials: true, // 允许跨域携带Cookie
}));

步骤2:完善Cookie序列化配置

修改Cookie的序列化参数,补充path、sameSite和secure字段,确保跨域场景下Cookie能被浏览器正确保存:

res.setHeader(
  "Set-Cookie",
  cookie.serialize("accessToken", accessToken, {
    maxAge: 1000 * 60 * 15,
    httpOnly: true,
    path: '/', // 确保Cookie在整个服务路径下有效
    // 生产环境需设置为'none'并配合secure: true,开发环境用'lax'
    sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
    // 生产环境必须开启(需HTTPS),开发环境可关闭
    secure: process.env.NODE_ENV === 'production',
  })
);

2. 前端(NextJS)修改

在fetch请求中添加credentials: 'include',让浏览器接收并保存跨域Cookie:

const resp = await fetch("http://localhost:5000/login", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data),
  credentials: 'include', // 关键:允许跨域请求携带/接收Cookie
});

注意事项

  • 开发环境下secure必须设为false,因为localhost使用HTTP协议;生产环境必须设为true,且网站需使用HTTPS
  • sameSite: 'none'仅在secure: true时生效,用于跨域场景;同域场景可使用lax或strict
  • 服务端CORS配置的origin必须与前端地址完全匹配(包括端口号),不能使用通配符*

内容的提问来源于stack exchange,提问作者PauloRamos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:01:05