Laravel中间件验证通过后未跳转至受保护路由问题排查
Token验证成功后无法跳转至受保护路由的问题排查
我用token_verify中间件保护路由,只有客户端发送的token与数据库中的值匹配时才允许访问。目前遇到的问题是:token验证成功后,无法跳转到受保护的/profile路由。直接访问路由或使用无效/无token时,中间件能正常拦截;但发送正确token的请求仅返回200状态码,不会跳转到profile页面,希望排查问题原因。
路由代码
Route::middleware('token_verify')->group(function () { Route::get('/profile', [App\Http\Controllers\User\ProfileController::class, 'profile_page']); });
控制器代码
namespace App\Http\Controllers\User; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Models\User; class ProfileController extends Controller { public function profile_page() { return view('partials.user.profile_page'); } }
中间件代码
namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use App\Models\User; class TokenVerify { public function handle(Request $request, Closure $next) { $token = $request->bearerToken(); if (!$token) { return response()->json(['message' => 'Unauthorized No Token'], 401); } $user = User::where('userToken', $token)->first(); if (!$user) { return response()->json(['message' => 'Unauthorized Invalid Token'], 401); } return $next($request); } }
前端JavaScript请求代码
function showProfile() { const baseUrl = `www.mywebsite.com`; const token = localStorage.getItem('userToken'); if(!token) { window.location.href = `${baseUrl}` + '/login'; return; } const requestOptions = { method: 'GET', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } }; // Make a GET request using Fetch API fetch(`${baseUrl}/profile`, requestOptions).then(response => { if(response.status === 200) { console.log(`response ok`); } else if(response.status === 401) { window.location.href = `${baseUrl}` + '/login'; } }).then(data => { console.log(data); }).catch(error => { console.error(error); }); }
问题原因分析
核心问题出在前端请求逻辑:你用fetch发送AJAX请求获取/profile页面内容,但仅在控制台打印了"response ok",完全没有处理返回的页面内容,自然不会触发页面跳转。
后端逻辑是正常的:验证通过后已经返回了profile页面的HTML,但前端没有把这些内容渲染到页面上,也没有执行跳转操作。
解决办法
根据需求,有两种常用处理方式:
方式1:直接跳转页面(推荐,符合传统网页逻辑)
不需要AJAX请求,直接修改window.location.href跳转到/profile路由。注意:如果后端依赖请求头的Authorization Token,需要先把token存入Cookie(推荐HttpOnly Cookie,更安全),这样跳转时浏览器会自动携带Cookie,后端中间件可以从Cookie中获取token验证。
修改前端代码:
function showProfile() { const baseUrl = `www.mywebsite.com`; const token = localStorage.getItem('userToken'); if(!token) { window.location.href = `${baseUrl}/login`; return; } // 直接跳转,替代AJAX请求 window.location.href = `${baseUrl}/profile`; }
方式2:渲染AJAX返回的页面内容
如果必须用AJAX请求,需要把后端返回的HTML内容替换当前页面的内容:
修改前端代码:
function showProfile() { const baseUrl = `www.mywebsite.com`; const token = localStorage.getItem('userToken'); if(!token) { window.location.href = `${baseUrl}/login`; return; } const requestOptions = { method: 'GET', headers: { 'Authorization': `Bearer ${token}` // 请求HTML不需要Content-Type: application/json } }; fetch(`${baseUrl}/profile`, requestOptions) .then(response => { if(response.status === 200) { return response.text(); // 获取HTML文本内容 } else if(response.status === 401) { window.location.href = `${baseUrl}/login`; } }) .then(html => { // 替换整个页面内容 document.body.innerHTML = html; // 也可以替换指定容器,比如document.getElementById('page-content').innerHTML = html; }) .catch(error => { console.error(error); }); }
注意:这种方式可能会丢失页面原有JS事件绑定,需额外处理,因此更推荐方式1。
内容的提问来源于stack exchange,提问作者aliencity
相关产品推荐
相关产品推荐

