在Next.js中如何获取NestJS后端设置的HttpOnly JWT Cookie?
我尝试在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列表,应该能看到jwtCookie(HttpOnly Cookie会有专属标记,无法通过JS读取)。 - 后续跨域请求(如获取用户信息接口)只要开启
withCredentials: true,浏览器会自动携带该HttpOnly Cookie到后端,后端可通过req.cookies.jwt获取并验证。
内容的提问来源于stack exchange,提问作者K. Gero
相关产品推荐
相关产品推荐

