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

同主机下Laravel Sanctum会话认证在Next.js服务端未授权问题

问题解决:Next.js服务端getServerSideProps请求Laravel Sanctum未授权

核心问题分析

客户端请求正常但服务端请求失败,本质是服务端环境下无法自动读取和传递Sanctum所需的会话Cookie与CSRF Token,同时存在代码引用错误和配置遗漏。

分步解决方案

1. 修复Axios实例引用错误

你的getServerSideProps中使用了未定义的ax.post,需替换为你创建的axiosInstance.post:

// 错误写法
// const response = await ax.post(...)

// 正确写法
const response = await axiosInstance.post(...)

2. 服务端手动处理CSRF Token

服务端无法直接访问浏览器Cookie,需从请求头中解析Cookie并手动添加X-XSRF-TOKEN请求头:
首先安装Cookie解析工具:

npm install cookie

然后修改getServerSideProps:

import { parse } from 'cookie';

export async function getServerSideProps(context) {
    const { query, req } = context;
    const { page, search_term, nip, tableName } = query;

    // 解析请求头中的Cookie
    const cookies = parse(req.headers.cookie || '');
    const xsrfToken = cookies['XSRF-TOKEN'];

    try {
        const response = await axiosInstance.post(
            `api/v1/admin/${tableName}`,
            { page: page, search_term: search_term, nip: nip || 10 },
            {
                withCredentials: true,
                headers: {
                    Cookie: req.headers.cookie,
                    // 解码并添加CSRF Token请求头
                    'X-XSRF-TOKEN': xsrfToken ? decodeURIComponent(xsrfToken) : '',
                }
            }
        );

        return {
            props: {
                initItems: response.data.data,
                initMeta: response.data.meta,
                initSearchTerm: search_term || '',
                iniNip: nip || 10
            }
        };
    } catch (err) {
        console.log(err);
        return { notFound: true };
    }
}

3. 调整Axios拦截器适配服务端

原拦截器依赖浏览器Cookie API,服务端环境下会失效,需添加服务端判断逻辑:

const onRequest = (config) => {
    // 服务端环境直接跳过CSRF Token预获取
    if (typeof window === 'undefined') {
        return config;
    }

    if (
        (config.method === 'post' || config.method === 'put' || config.method === 'delete') &&
        !Cookies.get('XSRF-TOKEN')
    ) {
        return setCSRFToken().then(response => config);
    }
    return config;
};

4. 验证Laravel配置正确性

确保Laravel后端允许跨域凭证传递并包含Next.js域名:

  • config/cors.php:
return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['http://localhost:3000'], // 你的Next.js地址
    'allowed_headers' => ['*'],
    'supports_credentials' => true, // 必须开启
];
  • config/sanctum.php:
return [
    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:3000,127.0.0.1:8000')),
];
  • .env:
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:3000,localhost:8000

内容的提问来源于stack exchange,提问作者Esmaeil Soomari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:06:03