You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:59:54