Next.js 13基于HTTP Cookie的认证问题求助
问题分析与解决方案
核心问题原因
- Fetch请求未携带Cookie凭证:默认情况下,
fetch不会自动发送浏览器存储的Cookie到服务器,导致GET请求无法携带之前POST设置的access_tokenCookie。 - POST API路由未返回合法响应:Next.js API路由必须返回标准
Response对象,否则浏览器无法正确确认请求完成状态,可能影响Cookie的后续读取。 - Server Context的Cookie隔离:App Router中
cookies()函数获取的是当前请求携带的Cookie,POST设置的Cookie仅存储在浏览器中,需后续请求主动携带才能被服务器读取。
修复步骤与代码示例
1. 修正Fetch请求的凭证配置
在cookie.ts的两个函数中添加credentials: 'same-origin',确保同域名请求携带Cookie:
export const setAuthToken = ( expiresIn: number, accessToken: string | null, baseUrl: string ) => { return fetch(`${baseUrl}/api/auth/login`, { method: "post", headers: { "Content-Type": "application/json", }, credentials: 'same-origin', // 新增:携带同域名Cookie body: JSON.stringify({ expiresIn, accessToken }), }); }; export const getAccessTokenCookie = async (baseUrl: string) => { const response = await fetch(`${baseUrl}/api/auth/login`, { method: "get", credentials: 'same-origin', // 新增:携带同域名Cookie }); const data = await response.json(); console.log(data, "data"); return data.token; };
2. 完善POST API路由的响应返回
在/app/api/auth/login/route.ts的POST函数中添加合法的响应返回:
import { cookies } from "next/headers"; export async function POST(request: Request) { const body = await request.json(); const { expiresIn, accessToken } = body; // 校验必填参数 if (!accessToken || typeof expiresIn !== 'number') { return new Response(JSON.stringify({ error: "Invalid parameters" }), { status: 400 }); } cookies().set({ name: "access_token", value: accessToken, httpOnly: true, secure: process.env.NODE_ENV !== "development", sameSite: "strict", maxAge: expiresIn, path: "/", }); // 返回标准响应 return new Response(JSON.stringify({ success: true }), { status: 200, headers: { "Content-Type": "application/json" } }); } export async function GET() { const accessToken = cookies().get("access_token"); console.log(accessToken, "accessToken"); if (!accessToken?.value) { return new Response(JSON.stringify({ token: null }), { headers: { "Content-Type": "application/json", }, }); } return new Response(JSON.stringify({ token: accessToken.value }), { headers: { "Content-Type": "application/json", }, }); }
额外注意事项
- 确保调用
setAuthToken和getAccessTokenCookie的代码运行在客户端组件中(使用'use client'指令),服务器端发起的fetch不会携带浏览器Cookie。 - 开发环境下确认
baseUrl与前端域名一致(如http://localhost:3000),避免跨域Cookie问题。
内容的提问来源于stack exchange,提问作者Edonis Alijaj
相关产品推荐
相关产品推荐

