Laravel 分组多个中间件
Laravel group multiple Middleware
在我的应用程序中,我有三个用户角色:
- 用户
- 编辑
- 管理员
当编辑器登录管理部分时,有些部分是隐藏的(用户管理、系统信息等),当然,管理员可以看到所有内容。
因此,为此我创建了两个中间件:Admin 和 Editor。这是代码。
管理中间件。
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class Admin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()) {
if(Auth::user()->role_id == 3) {
return $next($request);
}
}
return redirect('/');
}
}
编辑器中间件:
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class Editor
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()) {
if(Auth::user()->role_id == 2) {
return $next($request);
}
}
return redirect('/');
}
}
这是内核的一部分:
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\Admin::class,
'editor' => \App\Http\Middleware\Editor::class,
];
现在我正在尝试构建可供这些用户角色使用的路由。
如果我只为管理员或编辑做,它工作正常,但当我将它们组合在一起时,一个用户可以登录,另一个用户不能。
这是仅供管理员使用的代码,它运行良好。
Route::middleware('admin')->group(function(){
Route::get('/admin', 'PagesController@adminIndex');
Route::resource('/admin/pages', 'PagesController');
Route::resource('/admin/news', 'NewsController');
Route::resource('/admin/users', 'UsersController');
...
});
我尝试将它们与这段代码结合起来,但它不起作用(根本无法登录到管理部分):
Route::middleware(['admin', 'editor'])->group(function(){
Route::get('/admin', 'PagesController@adminIndex');
Route::resource('/admin/pages', 'PagesController');
Route::resource('/admin/news', 'NewsController');
Route::resource('/admin/users', 'UsersController');
...
});
我该如何解决这个问题?
P.S。后来我也想为用户角色建立一个逻辑,所以必须有一种方法来组合路由。
应该是下面这样的。
Route::middleware(['auth'])->group(function(){
//common routes will goes here
Route::middleware(['admin'])->group(function(){//admin routes will goes here
Route::get('/admin', 'PagesController@adminIndex');
Route::resource('/admin/pages', 'PagesController');
Route::resource('/admin/news', 'NewsController');
Route::resource('/admin/users', 'UsersController');
});
Route::middleware(['editor'])->group(function(){
//editor routes goes here.
});
});
问题是您的 middleware(['admin', 'editor']) 正在检查两个角色,即 admin,editor 用户,您只有一个用户角色。这就是它不起作用的原因
有很多很棒的软件包可以管理易于使用的用户角色。我建议你使用 Spatie Laravel Permission if you want tutorials on it watch Bitfumes Video
您可以在 Middleware Parameters 的帮助下解决问题,而不是为每个角色使用多个中间件,只使用一个以角色作为参数的通用中间件。
例如:
protected $routeMiddleware = [
'checkRole' => \App\Http\Middleware\CheckRole::class,
];
中间件:
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class CheckRole
{
public function handle($request, Closure $next, ...$roles)
{
$roleIds = ['user' => 1, 'editor' => 2, 'admin' => 3];
$allowedRoleIds = [];
foreach ($roles as $role)
{
if(isset($roleIds[$role]))
{
$allowedRoleIds[] = $roleIds[$role];
}
}
$allowedRoleIds = array_unique($allowedRoleIds);
if(Auth::check()) {
if(in_array(Auth::user()->role_id, $allowedRoleIds)) {
return $next($request);
}
}
return redirect('/');
}
}
路线:
Route::middleware(['checkRole:admin,editor'])->group(function(){
//Your routes
});
在我的应用程序中,我有三个用户角色:
- 用户
- 编辑
- 管理员
当编辑器登录管理部分时,有些部分是隐藏的(用户管理、系统信息等),当然,管理员可以看到所有内容。
因此,为此我创建了两个中间件:Admin 和 Editor。这是代码。
管理中间件。
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class Admin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()) {
if(Auth::user()->role_id == 3) {
return $next($request);
}
}
return redirect('/');
}
}
编辑器中间件:
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class Editor
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()) {
if(Auth::user()->role_id == 2) {
return $next($request);
}
}
return redirect('/');
}
}
这是内核的一部分:
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\Admin::class,
'editor' => \App\Http\Middleware\Editor::class,
];
现在我正在尝试构建可供这些用户角色使用的路由。 如果我只为管理员或编辑做,它工作正常,但当我将它们组合在一起时,一个用户可以登录,另一个用户不能。
这是仅供管理员使用的代码,它运行良好。
Route::middleware('admin')->group(function(){
Route::get('/admin', 'PagesController@adminIndex');
Route::resource('/admin/pages', 'PagesController');
Route::resource('/admin/news', 'NewsController');
Route::resource('/admin/users', 'UsersController');
...
});
我尝试将它们与这段代码结合起来,但它不起作用(根本无法登录到管理部分):
Route::middleware(['admin', 'editor'])->group(function(){
Route::get('/admin', 'PagesController@adminIndex');
Route::resource('/admin/pages', 'PagesController');
Route::resource('/admin/news', 'NewsController');
Route::resource('/admin/users', 'UsersController');
...
});
我该如何解决这个问题?
P.S。后来我也想为用户角色建立一个逻辑,所以必须有一种方法来组合路由。
应该是下面这样的。
Route::middleware(['auth'])->group(function(){
//common routes will goes here
Route::middleware(['admin'])->group(function(){//admin routes will goes here
Route::get('/admin', 'PagesController@adminIndex');
Route::resource('/admin/pages', 'PagesController');
Route::resource('/admin/news', 'NewsController');
Route::resource('/admin/users', 'UsersController');
});
Route::middleware(['editor'])->group(function(){
//editor routes goes here.
});
});
问题是您的 middleware(['admin', 'editor']) 正在检查两个角色,即 admin,editor 用户,您只有一个用户角色。这就是它不起作用的原因
有很多很棒的软件包可以管理易于使用的用户角色。我建议你使用 Spatie Laravel Permission if you want tutorials on it watch Bitfumes Video
您可以在 Middleware Parameters 的帮助下解决问题,而不是为每个角色使用多个中间件,只使用一个以角色作为参数的通用中间件。
例如:
protected $routeMiddleware = [
'checkRole' => \App\Http\Middleware\CheckRole::class,
];
中间件:
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class CheckRole
{
public function handle($request, Closure $next, ...$roles)
{
$roleIds = ['user' => 1, 'editor' => 2, 'admin' => 3];
$allowedRoleIds = [];
foreach ($roles as $role)
{
if(isset($roleIds[$role]))
{
$allowedRoleIds[] = $roleIds[$role];
}
}
$allowedRoleIds = array_unique($allowedRoleIds);
if(Auth::check()) {
if(in_array(Auth::user()->role_id, $allowedRoleIds)) {
return $next($request);
}
}
return redirect('/');
}
}
路线:
Route::middleware(['checkRole:admin,editor'])->group(function(){
//Your routes
});