如何基于Laravel Fortify实现仅admin角色用户可登录的功能
实现Laravel Fortify仅允许管理员登录的方案
你可以直接在Fortify的登录验证流程里加角色判断,比后加中间件拦截更合理,不会出现用户先登录成功再被踢出的情况,具体实现步骤如下:
步骤1:配置用户与角色的关联关系
首先确保User模型已经配置好和Role模型的关联,假设users表有role_id外键关联roles表主键,roles表用name字段存储角色标识:
// app/Models/User.php public function role() { return $this->belongsTo(Role::class); }
如果是多对多角色关联,可把关联方法改成belongsToMany。
步骤2:自定义Fortify登录验证管道
Laravel Fortify的登录流程通过管道按顺序执行验证逻辑,我们可以在身份验证通过后新增角色校验步骤:
打开app/Providers/FortifyServiceProvider.php,在boot方法中重写登录管道配置:
use Laravel\Fortify\Actions\AttemptToAuthenticate; use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled; use Laravel\Fortify\Actions\PrepareAuthenticatedSession; use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable; use Laravel\Fortify\Features; use Laravel\Fortify\Fortify; use Illuminate\Http\Request; public function boot() { Fortify::authenticateThrough(function (Request $request) { return array_filter([ config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class, Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null, AttemptToAuthenticate::class, // 新增管理员角色校验步骤 \App\Actions\Fortify\ValidateAdminRole::class, PrepareAuthenticatedSession::class, ]); }); }
步骤3:创建管理员角色校验类
新建app/Actions/Fortify/ValidateAdminRole.php文件,写入校验逻辑:
<?php namespace App\Actions\Fortify; use Illuminate\Validation\ValidationException; class ValidateAdminRole { public function handle($request, $next) { // 校验当前登录用户角色是否为admin if (auth()->user()->role->name !== 'admin') { // 校验不通过先退出登录 auth()->logout(); // 抛出验证错误,返回前端提示 throw ValidationException::withMessages([ 'email' => ['您的账号没有后台登录权限'], ]); } return $next($request); } }
备选方案:用中间件实现(适合登录后全局拦截)
如果你确实需要用中间件做全局权限校验,实现逻辑如下:
- 生成中间件:执行命令
php artisan make:middleware AdminCheck - 写入中间件逻辑:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; class AdminCheck { public function handle(Request $request, Closure $next): Response { if (auth()->check() && auth()->user()->role->name !== 'admin') { auth()->logout(); return redirect()->route('login')->withErrors([ 'email' => '您的账号没有访问权限' ]); } return $next($request); } }
- 注册中间件:在
app/Http/Kernel.php的$routeMiddleware数组中添加'admin' => \App\Http\Middleware\AdminCheck::class, - 给需要管理员权限的路由加上
->middleware('admin')即可生效。
内容的提问来源于stack exchange,提问作者Abdl Mouty
相关产品推荐
相关产品推荐

