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

Next.js无法获取Laravel API设置的Cookie及CSRF令牌问题

Next.js中Axios自动携带CSRF令牌的问题排查与解决

我有一个Next.js应用,正尝试配置Axios以自动在所有非GET请求中携带CSRF令牌。调用的API会在浏览器中设置Cookie,但编写的代码从Cookie获取XSRF-TOKEN时遇到失败问题。

现有代码

function getCookie(name) {
  const cookie = document.cookie
    .split("; ")
    .find((item) => item.startsWith(`${name}=`));
  console.log(document.cookie); // Debug: check what cookies are present
  if (!cookie) return null;

  return decodeURIComponent(cookie.split("=")[1]); // Fixed: Correctly split the cookie value
}

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

axios.interceptors.request.use(async (req) => {
  if (req.method === "get") return req;

  let csrfToken = getCookie("XSRF-TOKEN");
  if (!csrfToken) {
    await axios.get("/sanctum/csrf-cookie");
    csrfToken = getCookie("XSRF-TOKEN");
  }
  req.headers["X-XSRF-TOKEN"] = csrfToken;
  return req;
});

export default axios;

遇到的问题

  • Cookie获取:getCookie函数无法始终正确获取XSRF-TOKEN。
  • Cookie设置:即使成功调用/sanctum/csrf-cookie接口,XSRF-TOKEN有时仍不存在。

已尝试操作

  • 调试document.cookie:添加控制台日志查看文档中的Cookie。
  • 手动请求/sanctum/csrf-cookie:尝试手动访问该端点以确保CSRF Cookie已设置。

疑问

  1. Next.js应用中是否有更优的Cookie获取方式?
  2. 是否存在特定的浏览器设置或CORS配置会干扰Cookie处理?
  3. 如何确保CSRF令牌在不同环境和浏览器中能可靠设置与获取?

请求头Cookie截图

请求头中的Cookie截图


问题分析与解决方案

1. 优化Cookie获取方式

Next.js提供了更可靠的Cookie获取方案,分场景选择:

  • 服务端组件(App Router):用官方next/headers的cookies()方法安全读取Cookie,不受客户端限制:
import { cookies } from 'next/headers';

export function getServerCsrfToken() {
  const cookieStore = cookies();
  return cookieStore.get('XSRF-TOKEN')?.value;
}
  • 客户端组件:修复getCookie函数的鲁棒性,处理Cookie中可能的空格或边界情况:
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
  return null;
}

2. 排查浏览器与CORS配置问题

  • 浏览器设置:
    • 检查是否禁用第三方Cookie(跨域场景下会导致Cookie无法读取),Chrome需关闭"第三方Cookie阻止"功能;
    • 查看Cookie的SameSite属性,若后端设为Strict,跨域请求时Cookie不会被携带,建议设为Lax或None(设None需配合Secure属性)。
  • 后端CORS配置:必须满足以下条件:
    • Access-Control-Allow-Origin:指定前端具体域名(不能用*,否则withCredentials不生效);
    • Access-Control-Allow-Credentials: true:开启允许携带Cookie;
    • Access-Control-Allow-Headers: X-XSRF-TOKEN, Content-Type:允许自定义请求头。

3. 确保CSRF令牌可靠设置与获取

  • 利用Axios内置能力:你已经开启withXSRFToken: true,Axios会自动读取XSRF-TOKENCookie并设置X-XSRF-TOKEN请求头,无需手动拦截器重复处理,手动逻辑可能覆盖内置行为;
  • 修复拦截器竞态问题:如果必须保留拦截器,使用独立Axios实例调用CSRF接口,避免循环调用:
// 创建独立实例用于获取CSRF令牌,避免触发拦截器
const csrfAxios = Axios.create({
  baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
  withCredentials: true,
});

axios.interceptors.request.use(async (req) => {
  if (req.method?.toLowerCase() === 'get') return req;
  
  let csrfToken = getCookie('XSRF-TOKEN');
  if (!csrfToken) {
    await csrfAxios.get('/sanctum/csrf-cookie');
    csrfToken = getCookie('XSRF-TOKEN');
  }
  req.headers['X-XSRF-TOKEN'] = csrfToken;
  return req;
});
  • 检查后端Cookie属性:设置XSRF-TOKEN时需确保:
    • HttpOnly: false:必须关闭,否则客户端JavaScript无法读取;
    • Path: /:确保Cookie在全站范围内可用;
    • 开发环境禁用Secure属性(除非用HTTPS),否则Cookie不会被设置。

内容的提问来源于stack exchange,提问作者Kamran Ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:34:52