我目前在 Next.js 14 路由处理程序中设置 cookie 时遇到问题。我已通过控制台日志确认令牌已正确包含在 Set-Cookie 标头中,但 cookie 未出现在浏览器中。我尝试过调整 SameSite、secure 和 httpOnly 等各种选项,但似乎没有任何效果。可能是什么问题呢?下面是我的代码:
//应用程序/auth/login/page.tsx
import { redirect } from 'next/navigation';
import { LoginPage } from 'common';
interface Params {
searchParams?: { [key: string]: string | undefined };
}
const Login = async ({ searchParams }: Params) => {
const loginCode = searchParams?.code;
if (loginCode) {
const res = await fetch(
new URL(`/auth/login/post?code=${loginCode}`, process.env.BASE_URL),
{
method: 'POST',
}
);
console.log(res.headers.getSetCookie()); // (1)
redirect('/');
}
return <LoginPage />;
};
export default Login;
//app/auth/login/post/route.ts
import { cookies } from 'next/headers';
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import type { TokenResponseLoginType } from 'types';
export async function POST(request: NextRequest) {
const cookieStore = cookies();
try {
.
.
.
const tokenData: TokenResponseLoginType = await res.json();
cookieStore.set('refresh_token', tokenData.refreshToken);
cookieStore.set('access_token', tokenData.accessToken);
// just try. (before -> return Response.redirect . . .)
return new Response('response', {
status: 200,
headers: {
'Set-Cookie': `refresh_token=${tokenData.refreshToken}; access_token=${tokenData.accessToken}`,
},
});
} catch (e) {
return NextResponse.redirect(new URL('/auth/login', request.url));
}
}
(1) ['access_token=blablabla;路径=/']
我觉得我已经尝试了有关cookie的所有方法。我在设置cookie时调整了选项,甚至更换了浏览器。以下是我尝试过的方法:
将 SameSite 选项设置为“严格”、“宽松”和“无”。 打开和关闭安全选项。 设置和取消设置 httpOnly 选项。 检查并调整cookie域和路径。 通过控制台日志确认 Set-Cookie 标头已正确包含在服务器响应中。 跨不同浏览器进行测试,看看问题是否是特定于浏览器的。 确保服务器在正确的环境(开发或生产)中运行以匹配 cookie 设置。
为了在下一个js 14中的api路由中设置cookie。您必须返回设置cookie的响应
//api/[myroute]/route.ts
const res = NextResponse.json({})
const newExpires = new Date(Date.now() + cookieValidTime)
res.cookies.set(
'session',
JSON.stringify({
...oldSession,
user: {
...oldSession.user,
...updatedFields,
expires: newExpires,
},
} as ISession),
{
expires: newExpires,
httpOnly: true,
}
)
return res
另外,以防万一动态页面可能被下一个服务器缓存,您可以在 next.config.mjs 文件中将动态页面时间设置为 0 秒
//next.config.mjs
experimental: {
staleTimes: {
dynamic: 0, // default is 30
static: 180,
},
},