Laravel Sanctum登录后访问受保护路由返回401未认证求助
React SPA 配置 Laravel Sanctum 认证后访问受保护路由返回401未认证
环境信息
- SPA地址:
localhost:3000 - 后端地址:
https://local-erp.XXX.com/
配置文件
sanctum.php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,https://local-erp.XXX.com', Sanctum::currentApplicationUrlWithPort() ))),
kernel.php
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\ThrottleRequests::class . ':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];
.env
SESSION_DOMAIN:.localhost
曾尝试设置为*.localhost和localhost
LoginController 代码
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use App\Service\Ldap; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; class LoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = RouteServiceProvider::HOME; public function __construct() { $this->middleware('guest')->except('logout'); } public function username() { return 'username'; } protected function credentials(Request $request) { return [ 'sAMAccountName' => $request->username, 'password' => $request->password ]; } }
前端请求代码
登录请求
axios.get("https://local-erp.XXX.com/sanctum/csrf-cookie").then(response => { axios.post("https://local-erp.XXX.com/login", {username: "xxx", password: "xxxx"}) })
以上请求均返回204状态码。
测试受保护路由请求
const querytest = () => { axios.get('https://local-erp.XXX.com/api/users/5/holiday-balance') }
返回结果:{"message":"Unauthenticated."}
解决方案建议
1. 开启Axios跨域Cookie传递
Sanctum依赖Cookie传递会话状态,前端必须开启withCredentials:
// 在axios初始化时添加全局配置 axios.defaults.withCredentials = true; // 建议设置baseURL简化请求 axios.defaults.baseURL = 'https://local-erp.XXX.com';
2. 修正后端CORS配置
修改config/cors.php,确保允许跨域凭证并包含前端域名:
return [ 'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'], 'allowed_methods' => ['*'], 'allowed_origins' => ['http://localhost:3000'], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, ];
3. 修正SESSION_DOMAIN配置
由于后端域名local-erp.XXX.com与前端localhost:3000是不同域,需将.env中的SESSION_DOMAIN设为后端域名:
SESSION_DOMAIN=local-erp.XXX.com
4. 清理Sanctum Stateful Domains
移除stateful配置中的后端域名,只保留前端相关地址,修改.env:
SANCTUM_STATEFUL_DOMAINS=localhost,localhost:3000
或直接修改sanctum.php:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:3000,127.0.0.1')),
5. 验证路由中间件
确认受保护路由在routes/api.php中正确使用auth:sanctum中间件:
Route::get('/users/{user}/holiday-balance', [UserController::class, 'getHolidayBalance']) ->middleware('auth:sanctum');
6. 清除缓存
修改配置后执行以下命令清除配置缓存:
php artisan config:clear php artisan cache:clear
内容的提问来源于stack exchange,提问作者Enzo
相关产品推荐
相关产品推荐

