我在将来自 Nestjs 后端的 cookie 设置到我的 nextjs 应用程序中时遇到问题。
我的 Nestjs 应用程序在端口 3001 上运行,这是我的引导程序
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: 'http://localhost:3000',
credentials: true,
});
app.use(cookieParser());
await app.listen(3001);
}
bootstrap();
为了测试它,我创建了一个 get 端点
@Get()
async getAll(@Req() request: Request, @Res() response: Response) {
console.log(request.cookies);
response.cookie('name', 'value', {
httpOnly: true,
secure: false,
sameSite: 'none',
});
return response.send('ok');
}
在 src/app/api/signin/route.ts 文件中的 nextjs 中我有这个
'use server'
import { NextRequest, NextResponse } from "next/server";
import axios, { AxiosHeaderValue } from 'axios';
import { cookies } from "next/headers";
export async function POST(request: NextRequest, res: NextResponse) {
const response = await axios.get("http://localhost:3001/test", {
headers: {
"Content-Type": "application/json"
},
withCredentials: true,
});
console.log(response.headers)
return new NextResponse(JSON.stringify(response.data))
}
一切顺利,console.log 打印了 set-cookie
Object [AxiosHeaders] {
'x-powered-by': 'Express',
'access-control-allow-origin': 'http://localhost:3000',
vary: 'Origin',
'access-control-allow-credentials': 'true',
'set-cookie': [ 'name=value; Path=/; HttpOnly; SameSite=None' ],
'content-type': 'text/html; charset=utf-8',
'content-length': '2',
etag: 'W/"2-eoX0dku9ba8cNUXvu/DyeabcC+s"',
date: 'Tue, 19 Mar 2024 09:45:14 GMT',
connection: 'keep-alive',
'keep-alive': 'timeout=5'
}
好极了!
但是如果我再次调用同一个端点,后端的
console.log(request.cookies);
我会得到空值。
set-cookie 指令不应该在后端设置 cookie 吗?对于 axios withCredentials 来说,它应该使用它们,对吗?
我错过了什么?我可能会感到困惑,因为 nextjs 教程非常古怪,我正在尝试做一些应该相对简单的事情,但在过去的两天里我一直在思考这个问题,我似乎无法设置请求中的 cookie...
您的 NestJS 后端 配置为接受来自在
localhost:3000
上运行的 Next.js 应用程序的请求,并在客户端上设置 cookie。
NestJS App (Port 3001) ──> Enable CORS for Next.js App (Port 3000)
│
└── Set-Cookie on Response
在您的 Next.js 应用程序中,您正在向 NestJS 后端发出请求,并期望保存 cookie 并在后续请求中发回。
Next.js App (Port 3000) ──> Axios Request to NestJS (Port 3001)
│ │
│ <── Set-Cookie [name=value] │
│ │
└── Subsequent Request ───────┘
(Expecting Cookies)
当您从 Next.js 服务器端代码(使用 Axios)发出 HTTP 请求时,Next.js 应用程序确实会收到
set-cookie
标头,如日志中所示。但是,这些 cookie 需要在客户端浏览器上显式设置,才能自动包含在后续请求中。 Axios(或任何服务器端 HTTP 请求库)不会像浏览器那样自动处理 cookie。
'use server';
import { NextRequest, NextResponse } from "next/server";
import axios from 'axios';
export async function POST(request: NextRequest) {
const backendResponse = await axios.get("http://localhost:3001/test", {
headers: {
"Content-Type": "application/json" // This header is included for completeness but is optional for GET requests
},
withCredentials: true,
});
// Extract cookies from the Axios response
const setCookieHeader = backendResponse.headers['set-cookie'];
// Create a new NextResponse object with the backend response data
const response = new NextResponse(JSON.stringify(backendResponse.data), {
headers: {
'Content-Type': 'application/json'
}
});
// If there are cookies, set them in the NextResponse headers to forward them to the client
if (setCookieHeader) {
response.headers.set('Set-Cookie', setCookieHeader.join(','));
}
return response;
}