Laravel Sanctum XHR请求返回401未认证问题求助
Laravel Sanctum 请求返回401未授权问题解决
问题场景
我有多个通过web路由访问的Blade页面(如/、about-us、/dashboard),其中/dashboard仅对已登录用户开放。在dashboard页面中,我用原生JS发送GET请求到api路由时,返回401错误,提示Object { message: "Unauthenticated." }。
相关代码
web.php
Route::get('/dashboard', function () { return view('dashboard'); })->middleware(['auth'])->name('dashboard');
api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });
Blade页面中的JS代码
async function send(method, url = "/api/users") { const rawResponse = await fetch(url, { method: method, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', } }, 2000); const content = await rawResponse.json(); return content; }
Kernel.php
'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ],
已尝试操作
我尝试在请求头中加入XSRF Token,但问题未解决:
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content') // ... headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRF-TOKEN': token },
另外,我仅运行了Sanctum的迁移(生成personal_access_token表),未做其他配置,该表目前为空。
问题原因及解决方案
核心原因
对于同域的Blade应用,Sanctum属于「有状态前端认证」,不需要使用个人访问令牌,而是通过laravel_session Cookie来识别用户。但当前配置有两个关键缺失:
- 未启用Sanctum的
EnsureFrontendRequestsAreStateful中间件,导致API路由无法识别同域请求的会话Cookie; - Fetch请求默认不携带Cookie,服务器无法获取
laravel_session来认证用户。
具体修复步骤
- 启用
EnsureFrontendRequestsAreStateful中间件
修改Kernel.php中的api中间件组,取消注释对应行:
'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ],
- 让Fetch请求携带Cookie
修改JS代码,添加credentials: 'include'配置(同域场景也可用credentials: 'same-origin'),同时保留XSRF Token头:
async function send(method, url = "/api/users") { const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); const rawResponse = await fetch(url, { method: method, credentials: 'include', // 携带会话Cookie headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRF-TOKEN': token } }); const content = await rawResponse.json(); return content; }
- 验证配置(可选)
如果是跨域场景需要额外配置sanctum.php中的stateful_domains,但同域Blade应用默认无需修改。
完成以上修改后,API路由就能通过laravel_session Cookie识别已登录用户,不会再返回401未授权错误。
内容的提问来源于stack exchange,提问作者Max Pattern
相关产品推荐
相关产品推荐

