Next.js服务端API请求传递认证凭证失败排查
问题解决:Next.js服务端组件请求Laravel Sanctum返回401
问题出在服务端组件的请求没有正确传递会话Cookie和CSRF令牌,具体修正点和原因如下:
核心问题分析
客户端组件的credentials: "include"会让浏览器自动附加当前用户的Cookie到请求中,但服务端组件运行在Next.js服务器上,无法直接获取用户浏览器的Cookie,必须手动处理Cookie传递;同时你对XSRF-TOKEN的取值方式有误。
修正后的代码
async function fetchDataServerSide(url: string) { 'use server' const userCookies = cookies(); const fetchPath = `${process.env.NEXT_PUBLIC_BACKEND_URL}/api/${url}`; // 手动构造Cookie头,传递用户的所有Cookie(包括会话Cookie) const cookieHeader = userCookies.getAll() .map(cookie => `${cookie.name}=${cookie.value}`) .join('; '); const options: RequestInit = { method: "GET", headers: { "Accept": "application/json", "Referer": process.env.APP_URL || '', "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/json", // 正确获取XSRF-TOKEN的value值 "X-CSRF-TOKEN": userCookies.get('XSRF-TOKEN')?.value || '', // 手动添加Cookie头,让Laravel能识别用户会话 "Cookie": cookieHeader } }; return await fetch(fetchPath, options); }
关键修正说明
- Cookie传递方式:服务端组件需要通过
cookies()获取用户的所有Cookie,手动构造Cookie请求头传递给Laravel——Laravel Sanctum需要会话Cookie来验证用户身份,这是服务端请求和客户端请求的核心区别。 - XSRF-TOKEN取值:
cookies().get('XSRF-TOKEN')返回的是包含name和value的对象,必须取.value属性作为请求头值,否则会传递无效的[object Object]导致CSRF验证失败。 - Credentials配置:服务端fetch不需要
credentials: "include",因为我们已经手动传递了Cookie头。
额外注意事项
- 确保Laravel的
config/sanctum.php中stateful_domains配置包含你的Next.js域名,否则跨域请求会被拦截。 - 确认
process.env.APP_URL配置正确,Referer头需要符合Laravel的CORS规则。
内容的提问来源于stack exchange,提问作者user101289
相关产品推荐
相关产品推荐

