React对接Laravel Sanctum遇401未授权及Cookie未发送问题求助
Laravel Sanctum + React 认证401问题排查与解决
针对你遇到的登录后请求受保护路由返回401、Cookie未设置/携带的问题,按以下步骤逐一排查修复:
1. 统一前后端域名(核心问题)
你的React运行在http://localhost:5173,Laravel却用http://127.0.0.1:8000——浏览器会把localhost和127.0.0.1视为不同源,导致Cookie无法跨源共享。
解决:
- 启动Laravel时指定host为localhost:
此时Laravel地址变为php artisan serve --host=localhosthttp://localhost:8000,和React同主域,Cookie可以正常共享。
2. 修正SESSION_DOMAIN与Sanctum配置
确保.env配置和前后端域名一致:
SANCTUM_STATEFUL_DOMAINS=http://localhost:5173 SESSION_DOMAIN=.localhost
修改后执行php artisan config:clear清除配置缓存。
3. 完善CORS配置
打开config/cors.php,确保以下配置正确:
return [ 'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'], 'allowed_methods' => ['*'], 'allowed_origins' => ['http://localhost:5173'], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, // 必须设为true,允许携带凭证 ];
执行php artisan config:clear生效。
4. 修正登录流程:先获取CSRF令牌
Sanctum要求POST请求必须携带CSRF令牌,登录前需先请求sanctum/csrf-cookie接口获取Cookie:
// 全局配置Axios(推荐) import axios from 'axios'; axios.defaults.withCredentials = true; axios.defaults.baseURL = 'http://localhost:8000'; // 登录流程 async function login() { try { // 第一步:获取CSRF令牌Cookie await axios.get('/sanctum/csrf-cookie'); // 第二步:发送登录请求 const response = await axios.post('/login', { email: 'test@example.com', password: 'password' }); console.log('登录成功', response.data); } catch (error) { console.error('登录失败', error.response.data); } }
5. 检查Laravel路由与中间件
- 确保登录路由不使用
auth:sanctum中间件(登录是未认证操作):// routes/api.php use App\Http\Controllers\AuthController; use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful; // 受保护路由组(需认证) Route::middleware(['api', EnsureFrontendRequestsAreStateful::class])->group(function () { Route::get('/user', function (Request $request) { return $request->user(); })->middleware('auth:sanctum'); }); // 登录路由(无需认证) Route::post('/login', [AuthController::class, 'login']); - 登录控制器的
login方法正确使用会话认证:// app/Http/Controllers/AuthController.php use Illuminate\Support\Facades\Auth; public function login(Request $request) { $credentials = $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); if (!Auth::attempt($credentials)) { return response()->json(['message' => '账号或密码错误'], 401); } return response()->json([ 'user' => Auth::user(), 'message' => '登录成功' ]); }
6. 浏览器验证Cookie
登录后打开浏览器开发者工具(F12),切换到Application -> Cookies -> http://localhost:8000,确认存在laravel_session和XSRF-TOKEN两个Cookie:
- 如果没有Cookie:检查前面的跨源、CSRF请求、CORS配置
- 如果有Cookie但请求未携带:检查Axios的
withCredentials是否全局配置,请求地址是否为localhost:8000
内容的提问来源于stack exchange,提问作者Umair Zubair
相关产品推荐
相关产品推荐

