我正在尝试在Laravel应用程序中执行基于角色的权限控制.我想检查一些用户可以执行哪些操作,但我无法弄清楚如何在我的模型中实现门和策略(权限描述在数据库中,并且是与存储资源的ID的表相关联的布尔值).
这是我使用的数据库模型:
我想知道laravel gate在我的情况下是否有用,我如何实现它,如果没有,如何制作一个基本的中间件来处理权限控制以保护路由(或控制器).
在表资源中,我有一个标识资源的uuid,别名是资源的名称,并且具有动作的点符号值或资源的上下文(例如'mysystem.users.create','mysystem.roles.delete ','mysystem.users.images.view').策略表有一个布尔"允许"字段,用于描述用户的权限.
提前致谢.
ker*_*rin 11
这是我使用策略在Laravel中实现基于角色的权限的方式.
用户可以拥有多个角色.角色具有关联权限.每个权限都允许对特定模型执行特定操作.
角色表
class CreateRolesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('label');
$table->text('description');
$table->timestamps();
});
}
// rest of migration file
Run Code Online (Sandbox Code Playgroud)
权限表
class CreatePermissionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('permissions', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('label');
$table->text('description');
$table->timestamps();
});
}
// rest of migration file
Run Code Online (Sandbox Code Playgroud)
权限角色数据透视表
class CreatePermissionRolePivotTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('permission_role', function (Blueprint $table) {
$table->integer('permission_id')->unsigned()->index();
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
$table->integer('role_id')->unsigned()->index();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->primary(['permission_id', 'role_id']);
});
}
// rest of migration file
Run Code Online (Sandbox Code Playgroud)
角色用户数据透视表
class CreateRoleUserPivotTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->integer('role_id')->unsigned()->index();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->primary(['role_id', 'user_id']);
});
}
// rest of migration file
Run Code Online (Sandbox Code Playgroud)
用户
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function assignRole(Role $role)
{
return $this->roles()->save($role);
}
public function hasRole($role)
{
if (is_string($role)) {
return $this->roles->contains('name', $role);
}
return !! $role->intersect($this->roles)->count();
}
Run Code Online (Sandbox Code Playgroud)
角色
class Role extends Model
{
protected $guarded = ['id'];
protected $fillable = array('name', 'label', 'description');
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
public function givePermissionTo(Permission $permission)
{
return $this->permissions()->save($permission);
}
/**
* Determine if the user may perform the given permission.
*
* @param Permission $permission
* @return boolean
*/
public function hasPermission(Permission $permission, User $user)
{
return $this->hasRole($permission->roles);
}
/**
* Determine if the role has the given permission.
*
* @param mixed $permission
* @return boolean
*/
public function inRole($permission)
{
if (is_string($permission)) {
return $this->permissions->contains('name', $permission);
}
return !! $permission->intersect($this->permissions)->count();
}
}
Run Code Online (Sandbox Code Playgroud)
允许
class Permission extends Model
{
protected $guarded = ['id'];
protected $fillable = array('name', 'label', 'description');
public function roles()
{
return $this->belongsToMany(Role::class);
}
/**
* Determine if the permission belongs to the role.
*
* @param mixed $role
* @return boolean
*/
public function inRole($role)
{
if (is_string($role)) {
return $this->roles->contains('name', $role);
}
return !! $role->intersect($this->roles)->count();
}
}
Run Code Online (Sandbox Code Playgroud)
每个模型都需要一个策略.以下是模型的示例策略item
.该策略定义了四个操作的视图,创建,更新,删除的"规则".
class ItemPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the item.
*
* @param \App\User $user
* @return mixed
*/
public function view(User $user)
{
$permission = Permission::where('name', 'items-view')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can create items.
*
* @param \App\User $user
* @return mixed
*/
public function create(User $user)
{
$permission = Permission::where('name', 'items-create')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can update the item.
*
* @param \App\User $user
* @return mixed
*/
public function update(User $user)
{
$permission = Permission::where('name', 'items-update')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can delete the item.
*
* @param \App\User $user
* @return mixed
*/
public function delete(User $user)
{
$permission = Permission::where('name', 'items-delete')->first();
return $user->hasRole($permission->roles);
}
}
Run Code Online (Sandbox Code Playgroud)
注册每个政策 AuthServiceProvider.php
use App\Item;
use App\Policies\ItemPolicy;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
Item::class => ItemPolicy::class,
];
// rest of file
Run Code Online (Sandbox Code Playgroud)
在每个控制器中,请参阅策略中的相应授权操作.
例如,在以下index
方法中ItemController
:
public function index()
{
$this->authorize('view', Item::class);
$items = Item::orderBy('name', 'asc')->get();
return view('items', ['items' => $items]);
}
Run Code Online (Sandbox Code Playgroud)
在您的视图中,您可以检查用户是否具有特定角色:
@if (Auth::user()->hasRole('item-administrator'))
// do stuff
@endif
Run Code Online (Sandbox Code Playgroud)
或者如果需要特定许可:
@can('create', App\User::class)
// do stuff
@endcan
Run Code Online (Sandbox Code Playgroud)
回答您的问题:如何制作一个基本的中间件来负责权限控制以保护路由(或控制器)?。
只是一个例子:
这是您的路由的简单角色中间件
AdminRole
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class AdminRole
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::user()->role->name!=="admin"){ //Check your users' role or permission, in my case only admin role for routes
return redirect('/access-denied');
}
return $next($request);
}
}
Run Code Online (Sandbox Code Playgroud)
定义此中间件后将kernel.php文件更新为
protected $routeMiddleware = [
..............
'admin' =>\App\Http\Middleware\AdminRole::class,
...................
];
Run Code Online (Sandbox Code Playgroud)
并使用此路由中间件:
使用路由中间件有不同的方法,但以下是一个示例
Route::group(['middleware' => ['auth','admin']], function () {
Route::get('/', 'AdminController@index')->name('admin');
});
Run Code Online (Sandbox Code Playgroud)
注意: laravel 上有一些用于角色和权限的工具和库,但上面是创建基本路由中间件的示例。
归档时间: |
|
查看次数: |
7086 次 |
最近记录: |