Laravel 具有 OR 条件的路由中的多个中间件
Laravel Multiple Middleware in Route with OR Condition
我想知道我是否可以在 Laravel 路线中做到这一点。假设我有 Admin
、Premium
和 User
(也可以使用 Auth
登录)中间件。另外,我的控制器有这样的方法:index
、create
、edit
、delete
我希望 Admin
能够做所有这些事情,但是Premium
只能访问index
方法,User
不能访问这个controller里面的任何东西(他可以访问另一个controller)。我知道我可以像这样使用 except
或 only
中间件方法:
public function __construct()
{
$this->middleware('premium')->only('index');
$this->middleware('admin');
// or maybe $this->middleware('admin')->except('index');
}
但是当我尝试将这两个中间件放在 __construct
方法中时,它们将开始相互冲突,这是有道理的,因为 Premium Member
可以访问索引方法,但之后不能由 Admin
本身访问。顺便说一句,我的中间件只是在检查:
if (Auth::check()) {
if (Auth::user()->role == 'Admin') {
return $next($request);
}
}
return redirect('/home');
所以,回到我的问题,我能否拥有 OR 中间件,这样我就可以避免来自多个中间件的冲突(当它们在同一个控制器构造函数中编写时,它们必须是 AND 条件)?
非常感谢。
如果你稍微改变一下你的逻辑思维方式,答案就会变得很简单。您可以创建新的中间件来检查它是否可以访问特定方法。
所以创建如下中间件'CanAccessIndex':
if (Auth::check()) {
if (Auth::user()->role == 'Admin' || Auth::user()->role == 'Premium') {
return $next($request);
}
}
return redirect('/home');
然后,您可以将该中间件放在索引函数上(而不是高级中间件),并将您的管理中间件放在除索引之外的所有内容上。像这样:
public function __construct()
{
$this->middleware('canAccessIndex')->only('index');
$this->middleware('admin')->except('index');
}
这是一种方法。
为此您需要中间件组,并且要管理访问层的这些层次结构,您可以简单地使用路由分组。
我将演示我的意思的示例:
假设您有 auth
中间件一般用于经过身份验证的用户(即每个人),然后另一个称为 premium
用于高级会员,admin
用于管理员。
然后您将根据访问级别分组:
Route::middleware('auth')->group(function(){
Route::middleware('premium')->group(function(){
Route::post('/create', 'HomeController@create')->middleware('admin');
Route::put('/update/{id}', 'HomeController@update')->middleware('admin');
Route::get('/index', 'HomeController@index');
Route::put('/delete/{id}', 'HomeController@delete')->middleware('admin');
});
});
因此您可以通过检查对您的中间件进行一般检查。如果您的角色级别为管理员 3 级和高级会员 2 级,那就容易多了。所以我们可以拥有高级中间件:
public function handle($request, Closure $next)
{
return auth()->user->role >= 2
? $next($request)
: redirect('/home');
}
这只是一个例子。您可以根据需要进行进一步检查,但更重要的是,确保您的 admin
中间件检查允许的确切角色级别。
我想知道我是否可以在 Laravel 路线中做到这一点。假设我有 Admin
、Premium
和 User
(也可以使用 Auth
登录)中间件。另外,我的控制器有这样的方法:index
、create
、edit
、delete
我希望 Admin
能够做所有这些事情,但是Premium
只能访问index
方法,User
不能访问这个controller里面的任何东西(他可以访问另一个controller)。我知道我可以像这样使用 except
或 only
中间件方法:
public function __construct()
{
$this->middleware('premium')->only('index');
$this->middleware('admin');
// or maybe $this->middleware('admin')->except('index');
}
但是当我尝试将这两个中间件放在 __construct
方法中时,它们将开始相互冲突,这是有道理的,因为 Premium Member
可以访问索引方法,但之后不能由 Admin
本身访问。顺便说一句,我的中间件只是在检查:
if (Auth::check()) {
if (Auth::user()->role == 'Admin') {
return $next($request);
}
}
return redirect('/home');
所以,回到我的问题,我能否拥有 OR 中间件,这样我就可以避免来自多个中间件的冲突(当它们在同一个控制器构造函数中编写时,它们必须是 AND 条件)?
非常感谢。
如果你稍微改变一下你的逻辑思维方式,答案就会变得很简单。您可以创建新的中间件来检查它是否可以访问特定方法。
所以创建如下中间件'CanAccessIndex':
if (Auth::check()) {
if (Auth::user()->role == 'Admin' || Auth::user()->role == 'Premium') {
return $next($request);
}
}
return redirect('/home');
然后,您可以将该中间件放在索引函数上(而不是高级中间件),并将您的管理中间件放在除索引之外的所有内容上。像这样:
public function __construct()
{
$this->middleware('canAccessIndex')->only('index');
$this->middleware('admin')->except('index');
}
这是一种方法。
为此您需要中间件组,并且要管理访问层的这些层次结构,您可以简单地使用路由分组。
我将演示我的意思的示例:
假设您有 auth
中间件一般用于经过身份验证的用户(即每个人),然后另一个称为 premium
用于高级会员,admin
用于管理员。
然后您将根据访问级别分组:
Route::middleware('auth')->group(function(){
Route::middleware('premium')->group(function(){
Route::post('/create', 'HomeController@create')->middleware('admin');
Route::put('/update/{id}', 'HomeController@update')->middleware('admin');
Route::get('/index', 'HomeController@index');
Route::put('/delete/{id}', 'HomeController@delete')->middleware('admin');
});
});
因此您可以通过检查对您的中间件进行一般检查。如果您的角色级别为管理员 3 级和高级会员 2 级,那就容易多了。所以我们可以拥有高级中间件:
public function handle($request, Closure $next)
{
return auth()->user->role >= 2
? $next($request)
: redirect('/home');
}
这只是一个例子。您可以根据需要进行进一步检查,但更重要的是,确保您的 admin
中间件检查允许的确切角色级别。