我正在尝试将操作权限设置为两个不同的用户角色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'));
});
此路由可由Admin或Normal_user访问。但在此中间件配置中,用户必须同时是Admin和Normal_User。如何在中间件参数传递中添加OR条件?或者还有其他方法可以给予许可吗?
以下是我的中间件
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);
}
有人可以回复吗?
答案 0 :(得分:11)
不是向handle方法添加多个参数,而是每次向应用程序添加新角色时都必须更新它,您可以将其设置为动态。
<强>中间件强>
/**
* 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::group(['middleware' => ['role_check:default,admin,manager']], function() {
Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
});
这将检查经过身份验证的用户是否至少提供了其中一个角色,如果是,则将请求传递给下一个中间件堆栈。当然,hasRole()
方法和角色本身需要由您实施。
答案 1 :(得分:10)
要添加多个参数,您需要使用逗号分隔它们:
Route::group(['middleware' => ['role_check:Normal_User,Admin']], function() {
Route::get('/user/{user_id}', array('uses' => 'UserController@showUserDashboard', 'as' => 'showUserDashboard'));
});
然后您可以在中间件中访问它们,如下所示:
public function handle($request, Closure $next, $role1, $role2) {..}
由此决定的逻辑取决于你实施,没有自动的方式来说&#34; OR&#34;。
答案 2 :(得分:1)
您可以在PHP 5.6+中使用3点(...)语法
您的中间件的句柄功能
public function handle($request, Closure $next, ...$roles)
{
foreach($roles as $role){
if ($request->user()->hasRole($role)){
return $next($request);
}
}
abort(404);
}
答案 3 :(得分:0)
在中间件类中
<?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 !');
}
}
在web.php或路由文件中
Route::get('/usertype', function() {
return response(['Accessed'], 200);
})->middleware([
'App\Http\Middleware\MustBeOFUserType:admin,author'
]);
在':admin,author'上记住空间,例如':admin,author'会导致错误
进行健全性检查,如果您是像我这样的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;
}
}
答案 4 :(得分:0)
//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);
}
答案 5 :(得分:0)
在中间件文件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);
}
并使用您需要传递的尽可能多的参数从web.php调用中间件:
Route::get('/approve', 'aController@approve') ->middleware('roles:admin');
Route::get('/dashboard','bController@dashboard')->middleware('roles:admin,user');
也不要忘记在Kernel.php中修改中间件密钥名称:
'roles' => \App\Http\Middleware\checkRole::class,