Laravel 10中AJAX POST请求被重定向至/login的问题排查
问题描述
在Laravel应用的api.php中定义了一组通过auth中间件保护的POST路由:
Route::middleware('auth')->group(function(){ Route::post('/image-recognition', [DashboardController::class, 'imageRecognize'])->name('image-recognition'); Route::post('/bolt-size/change', [DashboardController::class,'boltSizeQtyChange'])->name('bolt-size-qty-change'); Route::post('/register-submit', [RegisterController::class, 'register'])->name('register-submit'); });
同时使用Blade编写了AJAX请求的JS代码,请求已携带X-CSRF-TOKEN和laravel_session cookie,但仍被重定向至/login路径,无法通过auth中间件认证。
问题分析
- API路由默认认证Guard不匹配:Laravel的
api.php路由默认使用apiGuard(基于Token认证),而通过Blade发送请求时依赖的是webGuard的Session认证,直接使用auth中间件会默认走apiGuard,导致Session凭据不被识别。 - 请求Content-Type与发送数据不匹配:设置了
Content-type: multipart/form-data,但实际发送的是JSON字符串,这会导致Laravel无法正确解析请求数据,也可能间接影响认证流程。 - 无效的自定义头:
X-UID头并非Laravel认证系统认可的凭据,无法用来识别用户,属于冗余设置。
解决方案
1. 指定认证Guard为web
修改路由分组的中间件,明确使用web Guard的Session认证:
Route::middleware('auth:web')->group(function(){ Route::post('/image-recognition', [DashboardController::class, 'imageRecognize'])->name('image-recognition'); Route::post('/bolt-size/change', [DashboardController::class,'boltSizeQtyChange'])->name('bolt-size-qty-change'); Route::post('/register-submit', [RegisterController::class, 'register'])->name('register-submit'); });
2. 修正请求Content-Type
如果发送的是JSON数据,将Content-type改为application/json,并确保数据格式正确:
var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.withCredentials = true; xhr.setRequestHeader("X-Requested-With", 'XMLHttpRequest'); xhr.setRequestHeader("Content-type", 'application/json'); // 匹配发送的JSON数据 xhr.setRequestHeader("X-CSRF-Token","{{ csrf_token() }}"); // 移除无用的X-UID头 // xhr.setRequestHeader("X-UID","{{auth()->user()->id}}"); xhr.onload = function() { // onload code here }; xhr.onerror = function() { console.error('Network error occurred'); }; var data = JSON.stringify(requestData); xhr.send(data);
如果需要发送表单/文件数据,请使用FormData对象,此时无需手动设置Content-type(浏览器会自动生成正确的头):
var formData = new FormData(); // 向FormData添加数据,比如文件:formData.append('image', fileInput.files[0]); // 其他字段:formData.append('key', value); var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.withCredentials = true; xhr.setRequestHeader("X-Requested-With", 'XMLHttpRequest'); xhr.setRequestHeader("X-CSRF-Token","{{ csrf_token() }}"); xhr.onload = function() { // onload code here }; xhr.onerror = function() { console.error('Network error occurred'); }; xhr.send(formData);
3. 确保Session Cookie有效
- 检查
config/session.php中的domain、path、secure配置,确保与当前请求的域名、协议匹配(比如HTTPS环境下secure需设为true)。 - 确认浏览器允许携带Cookie(同域请求默认支持,跨域需额外配置)。
4. 确认用户登录状态
在Blade模板中包裹AJAX代码,确保仅在用户登录时才发送请求:
@if(auth()->check()) <script> // 你的AJAX代码 </script> @endif
内容的提问来源于stack exchange,提问作者Arvin
相关产品推荐
相关产品推荐

