Laravel中间件权限控制异常:管理员可访问用户仪表盘求助
Laravel 中间件权限控制问题解决
问题根源
你的user.dashboard路由(对应/home地址)没有配置权限校验中间件,只要是已登录用户就能访问,所以管理员账号可以直接进入用户仪表盘。而admin.dashboard路由因为加了isAdmin中间件,普通用户无法访问,这部分逻辑是正常的。
解决方案
方法1:创建普通用户专属中间件(推荐)
- 生成普通用户中间件:
php artisan make:middleware UserMiddleware
- 打开
app/Http/Middleware/UserMiddleware.php,编写权限校验逻辑:
namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class UserMiddleware { public function handle(Request $request, Closure $next) { // 先判断用户是否已登录 if (!Auth::check()) { return redirect('login'); } // 仅允许普通用户(role_as 不为1)访问该路由 if (Auth::user()->role_as != '1') { return $next($request); } // 管理员访问则重定向到管理员仪表盘并提示 return redirect()->route('admin.dashboard')->with('status', '无权访问用户仪表盘'); } }
- 在
app/Http/Kernel.php中注册中间件别名:
找到$routeMiddleware数组,添加以下别名:
'isUser' => \App\Http\Middleware\UserMiddleware::class,
- 修改路由配置,给用户仪表盘路由添加
isUser中间件:
Auth::routes(); Route::get('/home', [App\Http\Controllers\HomeController::class, 'index']) ->middleware('isUser') // 新增中间件限制 ->name('user.dashboard'); Route::get('/dashboard', [AdminController::class, 'index']) ->middleware('isAdmin') ->name('admin.dashboard');
方法2:调整现有中间件逻辑(可选)
如果不想新增中间件,可以修改AdminMiddleware的逻辑,但这种方式会让中间件职责不够单一,仅作参考:
// 修改AdminMiddleware的handle方法 public function handle(Request $request, Closure $next) { if (!Auth::check()) { return redirect('login'); } // 如果是管理员访问用户路由,直接重定向 if (Auth::user()->role_as == '1' && $request->routeIs('user.dashboard')) { return redirect()->route('admin.dashboard')->with('status', '无权访问用户仪表盘'); } // 管理员访问管理员路由则放行 if (Auth::user()->role_as == '1') { return $next($request); } // 普通用户访问管理员路由则拒绝 return redirect('login')->with('status','You Do Not Have Admin Rights'); }
然后给用户路由也加上isAdmin中间件:
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index']) ->middleware('isAdmin') ->name('user.dashboard');
但这种方式不够灵活,后续扩展角色会很麻烦,还是推荐方法1。
优化建议
- 把角色标识定义为常量,比如在
User模型中添加:
const ROLE_ADMIN = '1'; const ROLE_USER = '0';
这样在中间件中可以用Auth::user()->role_as == User::ROLE_ADMIN,避免硬编码数字,提高代码可读性和维护性。
- 所有权限校验中间件都先判断用户是否登录,避免未登录状态下调用
Auth::user()产生错误。
内容的提问来源于stack exchange,提问作者ToddM
相关产品推荐
相关产品推荐

