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

Next.js中cookies-next与Axios拦截器集成问题排查

解决Next.js中Axios拦截器使用cookies-next的setCookie无效问题

问题根源

cookies-next库在服务端和客户端的Cookie处理逻辑存在差异:

  • 服务端环境下,setCookie依赖req和res对象通过HTTP响应头写入Cookie,若不传这两个参数,服务端无法完成Cookie设置
  • 客户端环境下,若未指定path、maxAge等关键配置,可能导致Cookie仅在局部路径生效或立即过期,表现为设置无效

解决方案

1. 适配服务端场景:传入req/res参数

当Axios拦截器在服务端执行(如API路由、服务端组件中调用),必须将req和res传递给setCookie。以下是修改后的完整代码:

import axios from "axios";
import { getCookie, setCookie } from "cookies-next";

const axiosUser = axios.create({
    baseURL: process.env.NEXT_PUBLIC_BASE_URL_USER,
    headers: { "Content-Type": "application/json" },
    withCredentials: true,
});

const axiosLogin = axios.create({
    baseURL: process.env.NEXT_PUBLIC_BASE_URL_USER,
    headers: { "Content-Type": "application/json" },
    withCredentials: true,
});

axiosUser.interceptors.request.use(
    async (config) => {
        // 服务端读取Cookie需传入req
        const token = getCookie("TOKEN", { req: config.req });
        console.log("««««« token »»»»»", token);
        // 若需在请求头携带Token,添加以下代码
        // if (token) config.headers.Authorization = `Bearer ${token}`;
        return config;
    },
    (error) => Promise.reject(error),
);

axiosLogin.interceptors.response.use(
    async (response) => {
        const { token, refreshToken } = response.data;
        // 从请求配置中获取传入的req和res
        const { req, res } = response.config;

        const baseCookieOptions = {
            req,
            res,
            maxAge: 60 * 60 * 24 * 7, // 7天有效期,可按需调整
            path: "/", // 确保全站可访问该Cookie
            secure: process.env.NODE_ENV === "production", // 生产环境启用HTTPS传输
            sameSite: "strict", // 防范CSRF攻击
        };

        if (token) {
            setCookie("TOKEN", token, baseCookieOptions);
            console.log("««««« token »»»»»", token);
        }
        if (refreshToken) {
            setCookie("REFRESHTOKEN", refreshToken, {
                ...baseCookieOptions,
                maxAge: 60 * 60 * 24 * 14, // 刷新Token设置更长有效期
            });
            console.log("««««« refreshToken »»»»»", refreshToken);
        }
        return response;
    },
    (error) => Promise.reject(error),
);

export { axiosUser, axiosLogin };

服务端调用时传入req/res

以Pages Router的API路由为例,调用axiosLogin时需传入req和res:

// pages/api/login.js
import { axiosLogin } from "../../utils/axios";

export default async function handler(req, res) {
    try {
        // 将req、res传入axios配置
        const response = await axiosLogin.post("/login", req.body, { req, res });
        res.status(200).json(response.data);
    } catch (error) {
        res.status(error.response?.status || 500).json(error.response?.data || { message: "登录失败" });
    }
}

2. 客户端场景:完善Cookie配置

在客户端组件(需标记"use client")中调用时,无需传入req/res,但需确保Cookie配置正确:

// components/LoginForm.js
"use client";
import { axiosLogin } from "../utils/axios";

const LoginForm = () => {
    const handleLogin = async () => {
        try {
            await axiosLogin.post("/login", { username: "test", password: "test" });
            // 登录成功后Cookie已全局生效
        } catch (err) {
            console.error("登录失败:", err);
        }
    };

    return <button onClick={handleLogin}>登录</button>;
};

export default LoginForm;

额外检查项

  • 确认withCredentials: true已正确设置:该配置用于请求时携带Cookie,不影响设置,但确保后续请求能带上Token
  • 生产环境必须启用secure: true:仅HTTPS环境可设置带secure属性的Cookie,本地开发可忽略
  • 避免在静态生成(SSG)页面中调用:静态页面无服务端上下文,无法处理Cookie操作

内容的提问来源于stack exchange,提问作者Chu Phong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 02:47:04