【发布时间】:2022-02-24 22:36:09
【问题描述】:
我将在我的应用程序中将所有路由分配给管理员角色,将一些路由分配给操作角色,并将一些路由分配给其他角色。我尝试在 Laravel 8 中使用组中间件。
仅管理员角色的代码就可以正常工作。但是,当我将中间件添加到路由组中的其他角色时,它的功能并没有达到我的预期。
我的代码:
Web.php:
Route::middleware(['role:Admin'])->group(function () {
Route::get('/', function () {
return redirect('/home');
});
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('/employee_register', [App\Http\Controllers\EmployeeRegisterController::class, 'index'])->name('employee_register');
Route::post('/employee_register', [App\Http\Controllers\EmployeeRegisterController::class, 'save'])->name('employee_save');
Route::post('/DoAsync', [App\Http\Controllers\AjaxController::class,'ajaxTask'])->middleware('only.ajax');
Route::get('/job_booking', [App\Http\Controllers\JobBookingController::class, 'index'])->name('job_booking');
Route::post('/DoAsync_jb', [App\Http\Controllers\JobBookingAjaxController::class,'ajaxTask'])->middleware('only.ajax');
Route::post('/DoAsync_ai', [App\Http\Controllers\AssignInchargeAjaxController::class,'ajaxTask'])->middleware('only.ajax');
});
Route::middleware(['role:operation'])->group(function () {
Route::get('/', function () {
return redirect('/job_booking');
});
Route::get('/home', function(){
return redirect('/job_booking');
})->name('home');
Route::get('/job_booking', [App\Http\Controllers\JobBookingController::class, 'index'])->name('job_booking');
Route::post('/DoAsync_jb', [App\Http\Controllers\JobBookingAjaxController::class,'ajaxTask'])->middleware('only.ajax');
Route::post('/DoAsync_ai', [App\Http\Controllers\AssignInchargeAjaxController::class,'ajaxTask'])->middleware('only.ajax');
});
中间件 (EnsureUserHasRole):
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string $role)
{
//I received Call to a member function roles() on null error when accessing login and logout.
// So, I used this to avoid role check on login & logout routes.
if ( $request->route()->named('login') || $request->route()->named('logout') ) {
return $next($request);
}
elseif ($request->user()->roles()->where('role', '=', $role)->exists()) {
return $next($request);
}
abort(403);
}
}
型号:
用户:
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $fillable = [
'employee_id',
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
public function roles()
{
return $this->belongsToMany(Role::class, 'role_user');
}
}
角色:
class Role extends Model
{
use HasFactory;
public function users()
{
return $this->belongsToMany(User::class, 'role_user');
}
}
如果没有第二个中间件 (middleware(['role:operation'])),所有路由都将被访问。但是,然后添加它,EnsureUserHasRole 中间件中的if 条件执行abort(403)
我应该在web.php的中间件中使用任何if吗?
注意:middleware('only.ajax') 已用于确保仅在 Ajax 调用时访问控制器
【问题讨论】:
标签: php laravel routes laravel-8 laravel-middleware