Laravel 7 gates 中关于多重授权的更简洁的代码是什么?

Laravel 7 what's less verbose code on multiple authorizations in gates?

我正在 App\Providers\AuthServiceProvider 中为用户角色定义门。用户具有其角色的价值。 like : (1,2,3,4) 用户管理中赋予的角色,所有用户可以有多个权限。

用户角色是:

为了隐藏侧边栏的一些信息,我使用了 Blade 指令 (@can)。 我需要根据每个用户的授权隐藏侧边栏的部分。

我使用的有效且长期的方法是:

AuthServiceProvider.php

....

        Gate::define('personnel-method', function ($user) {
        if(in_array(1,explode(",",$user->yetki)))
            return true;
        else
            return false;

    });

    Gate::define('add-method', function ($user) {
        if(in_array(2,explode(",",$user->yetki)))
            return true;
        else
            return false;

    });

    Gate::define('user-method', function ($user) {
        if(in_array(3,explode(",",$user->yetki)))
            return true;
        else
            return false;

    });

    Gate::define('adding-method', function ($user) {
        if(in_array(4,explode(",",$user->yetki)))
            return true;
        else
            return false;

    });

.....

sidebar.blade.php:

<ul>
 @can('personnel-method') <li>Personnel Edit </li> @endcan
 @can('add-method') <li>Add institution</li>@endcan
 @can('user-method')<li>User Management</li>@endcan
 @can('adding-method') <li>Adding Record</li>@endcan
</ul>

那么是否有更简洁的代码来执行此操作?

要shorthand您的代码,您可以执行以下操作

    Gate::define('personnel-method', function ($user) {
        return in_array(1,explode(",",$user->yetki));
    });

    Gate::define('add-method', function ($user) {
        return in_array(2,explode(",",$user->yetki));
    });

    Gate::define('user-method', function ($user) {
        return in_array(3,explode(",",$user->yetki));
    });

    Gate::define('adding-method', function ($user) {
        return in_array(4,explode(",",$user->yetki))
    });

如果您使用的是 php 7.4,您还可以使用箭头函数

    Gate::define('personnel-method', fn ($user) =>  in_array(1,explode(",",$user->yetki)));
    Gate::define('add-method', fn ($user) => in_array(2,explode(",",$user->yetki)));
    Gate::define('user-method', fn ($user) =>  in_array(3,explode(",",$user->yetki)));
    Gate::define('adding-method', fn ($user) => in_array(4,explode(",",$user->yetki)));

您可以使用 attribute casting. You can either use the "array" cast and change the value in the database to JSON ([1,2,3,4]) or define a custom cast 来拆分字符串。

使用 array 转换:

class User extends Model {

  protected $casts = [
    'yetki' => 'array',
  ];

  //...
}

因此您可以将门更改为:

Gate::define('personnel-method', function ($user) {
  if(in_array(1, $user->yetki))
    return true;
  else
    return false;
});

并且由于您正在检查布尔值,因此您不必使用 if 而只需 return 条件:

Gate::define('personnel-method', function ($user) {
  return in_array(1, $user->yetki);
});

为了使其更易于阅读,您可以将该逻辑移至 User class:

上的方法
class User extends Model {
  public function hasRole($role)
  {
    return in_array($role, $this->yetki);
  }
}

最后,您可以在 class 中定义角色:

abstract class UserRole {
  const Personnel_Edit = 1;
  const Add_institution = 2;
  const User_Management = 3;
  const Adding_Record = 4;
}

并将门更改为:

Gate::define('personnel-method', function ($user) {
    return $user->hasRole(UserRole::Personnel_Edit);
});