如何在 Laravel 5.2 中使用 OR 条件将多个参数传递给中间件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38712282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass multiple parameters to middleware with OR condition in Laravel 5.2
提问by manoos
I am trying to set permission to access an action to two different user roles Admin, Normal_User as shown below.
我正在尝试为两个不同的用户角色 Admin、Normal_User 设置访问操作的权限,如下所示。
Route::group(['middleware' => ['role_check:Normal_User','role_check:Admin']], function() {
Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
});
This route can be accessed by either Admin or Normal_user. But in this middleware configuration, user is required to be both Admin and Normal_User. How can I add OR condition in middleware parameter passing? Or is there any other method to give permission?
Admin 或 Normal_user 均可访问此路由。但是在这个中间件配置中,用户需要同时是 Admin 和 Normal_User。如何在中间件参数传递中添加 OR 条件?或者有没有其他方法可以授予权限?
The following is my middleware
以下是我的中间件
public function handle($request, Closure $next, $role)
{
if ($role != Auth::user()->user_role->role ) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return response('Unauthorized.', 401);
}
}
return $next($request);
}
Can anyone please reply?
请问有人可以回复吗?
回答by Chris
To add multiple parameters, you need to seperate them with a comma:
要添加多个参数,您需要用逗号分隔它们:
Route::group(['middleware' => ['role_check:Normal_User,Admin']], function() {
Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
});
Then you have access them to in your middleware like so:
然后你可以在你的中间件中访问它们,如下所示:
public function handle($request, Closure $next, $role1, $role2) {..}
The logic from there is up to you to implement, there is no automatic way to say "OR".
那里的逻辑由您来实现,没有自动说“或”的方法。
回答by Denis Priebe
Instead of adding multiple arguments to your handle method and having to update it every time you add a new role to your application, you can make it dynamic.
无需向您的 handle 方法添加多个参数,并且每次向应用程序添加新角色时都必须更新它,您可以使其动态化。
Middleware
中间件
/**
* Handle an incoming request.
*
* @param $request
* @param Closure $next
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function handle($request, Closure $next) {
$roles = array_slice(func_get_args(), 2); // [default, admin, manager]
foreach ($roles as $role) {
try {
Role::whereName($role)->firstOrFail(); // make sure we got a "real" role
if (Auth::user()->hasRole($role)) {
return $next($request);
}
} catch (ModelNotFoundException $exception) {
dd('Could not find role ' . $role);
}
}
Flash::warning('Access Denied', 'You are not authorized to view that content.'); // custom flash class
return redirect('/');
}
Route
路线
Route::group(['middleware' => ['role_check:default,admin,manager']], function() {
Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
});
This will check if the authenticated user has at least one of the roles provided and if so, passes the request to the next middleware stack. Of course the hasRole()
method and the roles themselves will need to be implemented by you.
这将检查经过身份验证的用户是否至少具有提供的一个角色,如果是,则将请求传递给下一个中间件堆栈。当然,hasRole()
方法和角色本身需要您自己实现。
回答by Muhammet ?ztürk
You can use the 3 dot (...) syntax in PHP 5.6+
您可以在 PHP 5.6+ 中使用 3 点 (...) 语法
Your middleware's handle function
你的中间件的句柄函数
public function handle($request, Closure $next, ...$roles)
{
foreach($roles as $role){
if ($request->user()->hasRole($role)){
return $next($request);
}
}
abort(404);
}
回答by Alemoh Rapheal Baja
//please take note there must be space between ... $roles
//on your route make sure there is no space in between the roles
'checkRole:staff,admin'
public function handle($request, Closure $next, ... $roles)
{
foreach($roles as $role){
if ($request->user()->hasRole($role)){
return $next($request);
}
}
abort(404);
}
you can try this out also
Route::group(['middleware' => 'role:webdev|admin'], function () {
});
public function handle($request, Closure $next, $role)
{
$roles = collect(explode('|',$role));
if (! $request->user()->hasRole($roles)) {
abort(404, 'No Way');
}
return $next($request);
}
回答by RRR
This super easy dynamic implementation might come handy for someone, in your middlewear file checkRole.php:
这个超级简单的动态实现可能会派上用场,在你的中间件文件 checkRole.php 中:
public function handle($request, Closure $next, ... $roles)
{
$found = false;
foreach ($roles as $role) {
if (session('type') == $role) {
$found = true; break;
}
}
if (!$found) {
return back()->with('error','Access denied!');
}
return $next($request);
}
and call the middlewear from web.php with as much parameter you need to pass:
并使用您需要传递的尽可能多的参数从 web.php 调用中间件:
Route::get('/approve', 'aController@approve') ->middleware('roles:admin');
Route::get('/dashboard','bController@dashboard')->middleware('roles:admin,user');
also don't forget to modify the middlewear key name in your Kernel.php:
也不要忘记修改 Kernel.php 中的中间件键名:
'roles' => \App\Http\Middleware\checkRole::class,
回答by mwangaben
In the middleware class
在中间件类
<?php
namespace App\Http\Middleware;
use Closure;
use function abort;
use function array_flip;
use function array_key_exists;
use function array_slice;
use function func_get_args;
class MustBeOFUserType
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$roles = array_slice(func_get_args(), 2); // ['admin', 'author']
//flip $roles to get ['admin' => 0, 'author' => 1];
if (!auth()->guest() && array_key_exists(auth()->user()->role->name, array_flip($roles))) {
return $next($request);
}
abort(423, 'Sorry you are not authrized !');
}
}
in the web.php OR route file
在 web.php 或路由文件中
Route::get('/usertype', function() {
return response(['Accessed'], 200);
})->middleware([
'App\Http\Middleware\MustBeOFUserType:admin,author'
]);
Remember space on':admin,author' like ':admin, author' will result into errors
记住':admin,author'上的空格,例如 ':admin, author' 会导致错误
For sanity check and if your a TDD person like I am use this to test the middleware
为了健全性检查,如果你像我这样的 TDD 人用它来测试中间件
<?php
namespace Tests\Feature;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use function factory;
class MustBeOFUserTypeTest extends TestCase
{
use RefreshDatabase;
/** @test * */
public function it_accepts_the_admin()
{
$this->signIn(factory(User::class)->states('administrator')->create());
$this->get('/usertype')->assertStatus(200);
}
/** @test * */
public function it_rejects_normal_users()
{
$this->signIn();
$this->get('/usertype')->assertStatus(423);
}
/** @test **/
public function it_accepts_authors()
{
$this->signIn(factory(User::class)->states('author')->create());
$this->get('/usertype')->assertStatus(200);
}
public function signIn($user = null)
{
$u = $user ?: factory('App\User')->states('normal')->create();
$this->be($u);
return $this;
}
}