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

在Next.js中如何获取NestJS后端设置的HttpOnly JWT Cookie?

问题:NestJS设置HttpOnly Cookie后,Next.js前端无法获取

我尝试在NestJS后端设置HttpOnly Cookie存储JWT Token,以便后续在Next.js客户端中使用,但遇到了问题:浏览器网络面板能看到正确的Set-Cookie头,但前端无法读取该Cookie,站点Cookie列表里也看不到它。

后端设置Cookie的代码

@Post("auth/sign-in")
async signIn(@Body() credentials: SignInDto, @Res() res: Response) {
  try {
    const { user, token }: { user: Partial<User>; token: string } =
      await this.userService.signIn(credentials);

    delete user.password;

    res.cookie("jwt", token, { httpOnly: true, sameSite: "none" });

    res.status(200).send({ user: user });
  } catch (err: unknown) {
    throw new InternalServerErrorException(err);
  }
}

前端请求代码

const API_BASE_URL = 'http://localhost:8080';

export const signIn = async (email: string, password: string) => {
    try {
        const response = await axios.post(`${API_BASE_URL}/user/auth/sign-in`, {
            email,
            password,
        }, {withCredentials: false});

        if (response.status === 200) {
            console.log('User signed in successfully:', response.data);
            
            console.log(response.headers['set-cookie']); // 返回undefined
            
            return response;
        } else {
            return null;
        }
    } catch (error) {
        console.error('Error signing in:', error);
        return null;
    }
}

已配置的NestJS CORS

app.enableCors({
    origin: "http://localhost:3000",
    credentials: true,
});

问题原因及解决方法

1. 前端请求未开启withCredentials

你的前端请求中withCredentials设为了false,这是核心问题。跨域请求需要携带Cookie时,必须将这个选项设为true,否则浏览器会忽略响应中的Set-Cookie头,不会将Cookie存入浏览器。

修改前端请求代码:

const response = await axios.post(`${API_BASE_URL}/user/auth/sign-in`, {
    email,
    password,
}, {withCredentials: true}); // 改为true

2. HttpOnly Cookie的特性限制

HttpOnly Cookie本身就不能通过前端JavaScript代码直接读取,这是它的安全特性,目的是防止XSS攻击窃取Cookie。所以你通过response.headers['set-cookie']获取不到是正常的,且在document.cookie里也看不到这类Cookie。

3. Cookie配置补充

你设置了sameSite: "none",这个选项要求Cookie必须是Secure的(仅在HTTPS连接下发送),但当前使用的是HTTP协议(localhost:8080),这会导致浏览器拒绝存储Cookie。

解决方法:

  • 开发环境可暂时将sameSite改为"lax"或"strict":
    res.cookie("jwt", token, { httpOnly: true, sameSite: "lax" });
    
  • 生产环境必须使用HTTPS,同时保留sameSite: "none"并加上secure: true:
    res.cookie("jwt", token, { httpOnly: true, sameSite: "none", secure: true });
    

4. 验证Cookie是否生效

修改后,可通过以下方式验证:

  • 打开浏览器开发者工具 → 「应用」标签 → 「存储」→「Cookie」,查看localhost:8080下的Cookie列表,应该能看到jwt Cookie(HttpOnly Cookie会有专属标记,无法通过JS读取)。
  • 后续跨域请求(如获取用户信息接口)只要开启withCredentials: true,浏览器会自动携带该HttpOnly Cookie到后端,后端可通过req.cookies.jwt获取并验证。

内容的提问来源于stack exchange,提问作者K. Gero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 02:34:53