Next.js无法设置Cookie求助:JWT过期时Cookie不生效
核心问题分析
你当前的代码存在两个关键问题:
- Server Component的fetch不影响浏览器Cookie:Tasks页面是Server Component(组件内使用了顶层async/await),其中的
fetch是在服务器端执行的,API路由设置的Cookie只会存在于服务器端的请求上下文,不会同步到浏览器。 - API路由的Cookie设置方式错误:使用
cookies().set仅修改当前请求的Cookie上下文,不会向浏览器返回Set-Cookie响应头,浏览器无法感知到Cookie。
具体解决步骤
1. 修正API路由的Cookie设置逻辑
在App Router的API路由中,必须通过NextResponse对象设置Cookie,这样才会在响应中添加Set-Cookie头,让浏览器接收并存储Cookie:
import { NextRequest, NextResponse } from "next/server"; export interface IRefreshToken { accessToken: string, refreshToken: string } export async function POST(req: NextRequest) { const body = await req.json() as IRefreshToken; const response = NextResponse.json({ message: 'Cookie set successfully!' }); // 通过response对象设置Cookie response.cookies.set({ name: 'test', value: 'test', httpOnly: true, path: '/', // 生产环境必须开启secure(HTTPS下生效),localhost可忽略 secure: process.env.NODE_ENV === 'production', // 根据跨域情况设置sameSite,同域用lax/strict,跨域用none(需配合secure) sameSite: 'lax' }); return response; }
2. 将Cookie操作移到Client Component
浏览器的Cookie只能在客户端环境中被设置和读取,因此需要把调用API路由的逻辑移到Client Component中:
'use client'; // 标记为Client Component import { ITasks } from '@/interfaces/task.interface'; import { getTasks } from '@/request'; import { INTERNAL_API_URL } from '@/utils/endpoints.utils'; import Link from 'next/link'; import { useEffect, useState } from 'react'; export default function Tasks() { const [tasks, setTasks] = useState<ITasks[]>([]); useEffect(() => { const init = async () => { const res = await getTasks(); setTasks(res.data as ITasks[]); // 客户端fetch需添加credentials: 'include',允许携带和接收Cookie const c = await fetch(`${INTERNAL_API_URL}/api/auth`, { method: 'POST', body: JSON.stringify(res.tokens), credentials: 'include', headers: { 'Content-Type': 'application/json', }, }); const m = await c.json(); console.log(m); }; init(); }, []); return ( <main> {tasks.map((task) => ( <div key={task.id}> <h2>{task.title}</h2> <p>{task.description}</p> <Link href={`tasks/${task.id}`}>go to task</Link> </div> ))} </main> ); }
3. 验证Cookie的查看方式
httpOnly: true的Cookie无法通过document.cookie读取,需要在浏览器控制台的Application > Cookies面板中查看是否存在。
4. 排查跨域与CORS配置(若前后端不同域名)
如果你的NestJS后端和Next.js前端不在同一域名下,需确保NestJS开启CORS并允许携带凭证:
// NestJS main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors({ origin: ['你的前端域名'], // 例如http://localhost:3000 credentials: true, // 允许携带Cookie }); await app.listen(3001); } bootstrap();
内容的提问来源于stack exchange,提问作者user2411628
相关产品推荐
相关产品推荐

