Laravel 5.5 基于Session配置路由失效显示404,如何解决?
解决Laravel 5.5基于Session的路由访问问题
兄弟,你这个写法行不通的核心原因很简单:Laravel的路由文件是在请求生命周期的极早期就加载执行的,这时候Session还没被初始化呢!你用session()->has()判断的时候,根本拿不到用户的Session数据,自然这些路由就没被注册,访问时就会报404了。
正确的思路应该是:先注册所有需要的路由,再用路由中间件来做Session权限校验,这才符合Laravel的请求流程。下面是具体实现步骤:
1. 先正常注册所有路由
不管用户状态,先把路由都写在web.php里,同时给需要权限的路由绑定对应的中间件:
// web.php // 注意控制器类名要遵循大驼峰命名规范,比如GameController而不是gameController Route::any('/profile/view',"ProfileController@view")->middleware('auth.user'); Route::any('/game/new', "GameController@new")->middleware('auth.admin');
2. 创建自定义权限中间件
我们需要两个中间件,分别校验普通用户和管理员的Session:
第一步:生成中间件文件
执行Artisan命令创建中间件:
# 创建普通用户校验中间件 php artisan make:middleware AuthenticateUser # 创建管理员校验中间件 php artisan make:middleware AuthenticateAdmin
第二步:编写中间件逻辑
打开app/Http/Middleware/AuthenticateUser.php,写入用户校验逻辑:
<?php namespace App\Http\Middleware; use Closure; class AuthenticateUser { public function handle($request, Closure $next) { // 检查Session中是否存在user标识 if (!$request->session()->has('user')) { // 无权限时可以跳转到登录页,或者返回403禁止访问 return redirect('/login')->with('error', '请先登录账号'); // 或者直接返回403:abort(403, '无访问权限'); } // 有权限则继续执行请求 return $next($request); } }
同样,打开app/Http/Middleware/AuthenticateAdmin.php,写入管理员校验逻辑:
<?php namespace App\Http\Middleware; use Closure; class AuthenticateAdmin { public function handle($request, Closure $next) { if (!$request->session()->has('admin')) { return redirect('/admin/login')->with('error', '请以管理员身份登录'); // abort(403, '无管理员权限'); } return $next($request); } }
3. 注册中间件到路由中间件组
打开app/Http/Kernel.php,找到$routeMiddleware数组,添加我们的自定义中间件:
protected $routeMiddleware = [ // 其他默认中间件... 'auth.user' => \App\Http\Middleware\AuthenticateUser::class, 'auth.admin' => \App\Http\Middleware\AuthenticateAdmin::class, ];
补充说明
为什么不能用动态注册路由的方式?因为Laravel的路由是在框架启动阶段就编译完成的,而Session的初始化是在请求处理阶段才完成的,两者的执行顺序导致你在路由文件里拿不到Session数据。
用中间件的方式,是在请求到达控制器之前进行权限校验,这完全符合Laravel的请求生命周期流程,也是官方推荐的权限控制方式。
内容的提问来源于stack exchange,提问作者pedropicapiedra
相关产品推荐
相关产品推荐

