You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13基于HTTP Cookie的认证问题求助

问题分析与解决方案

核心问题原因

  1. Fetch请求未携带Cookie凭证:默认情况下,fetch不会自动发送浏览器存储的Cookie到服务器,导致GET请求无法携带之前POST设置的access_token Cookie。
  2. POST API路由未返回合法响应:Next.js API路由必须返回标准Response对象,否则浏览器无法正确确认请求完成状态,可能影响Cookie的后续读取。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:12:28