实体间的关系
现在有三个实体:用户、角色、权限,首先我们搞清楚他们之间的关系是什么
用户有:张三、李四、王五
角色有:员工、经理、老板
权限有:删帖、看帖、
RBAC 基于角色的权限控制
RBAC模型的优势简化了用户和权限的关系
涉及到三个模型 用户模型 角色模型 权限模型
RBAC流程图
多对多关系:一个用户对多个角色,一个角色对多个权限
1.数据库设计
角色表
blog_role
id role_name
权限表
blog_permission
id per_name per_url
角色关联权限表
blog_role_premission
role_id permission_id
用户关联角色表
blog_user_role
user_id role_id
先做添加再做展示然后做授权
//授权方法
public function auth($id)
{
$role=Role::find($id);//通过$id获取当前角色
$perms=Permission::get();//获取所有权限列表
$own_perms=$role->permission;//获取当前角色拥有的权限 在我们的角色模型增加一个动态属性
//角色拥有的权限id
$own_pers=[];
foreach ($own_perms as $v){
$own_pers[]=$v->id;
}
return view('admin/role/auth',compact('perms','role','own_pers'));
}
在角色模型写
public function permission()
{
//添加动态属性,关联权限模型
//多对多关系 1.关联模型 2.关联表表名 3.当前模型在关联中的外键 4.被关联模型在关联表中的主键
return $this->belongsToMany('App\Model\Permission','blog_role_permission','role_id','permission_id');
}
执行权限处理
public function doauth(Request $request)
{
$inp=$request->except('_token()');
// 删除当前角色已有的权限
\DB::table('blog_role_permission')->where('role_id',$inp['role_id'])->delete();
if(!empty($inp['permission_id'])){
//因为是数组要遍历一下
foreach ($inp['permission_id'] as $v){
//添加新赋予的权限 万一传过来是个空所以要判断一下
\DB::table('blog_role_permission')->insert([
'role_id'=>$inp['role_id'],
'permission_id'=>$v
]);
}
}
return redirect('admin/role');
}
前台复选框
<div class="layui-input-inline" style="width:600px;">
@foreach($perms as $v)
{{--让用户拥有的权限被选中--}}
@if(in_array($v->id,$own_pers))
<input type="checkbox" name="permission_id[]" checked value="{{$v->id}}" title="{{$v->per_name}}" lay-skin="primary" >
@else
<input type="checkbox" name="permission_id[]" value="{{$v->id}}" title="{{$v->per_name}}" lay-skin="primary" >
@endif
@endforeach
</div>
新建一个中间件HaRole
public function handle($request, Closure $next)
{
//获取当前的请求路由 对应控制器方法
$route=$request->route()->getActionName();
// 2. 获取当前用户的权限组 我们先通过用户找到角色
$user = User::find(session()->get('user')->user_id);
//获取当前用户的角色 role已经定义好了
$roles=$user->role;
//role是个集合不能直接找角色需要遍历一下
//根据用户拥有的角色 找对应的权限
$arr=[];//定义一个空数组 存放权限对应的字段per_url
// "App\Http\Controllers\Admin\LoginController@index"
foreach($roles as $v){
$perms=$v->permission;//取出当前角色的权限 权限也是个集合
foreach ($perms as $perm){
$arr[]=$perm->per_url;
}
}
//去掉重复的权限
$arr=array_unique($arr);
//判断当前请求的路由对应控制器的方法名是否在当前用户
// 拥有的权限列表中也就是$arr中
if(in_array($route,$arr)){
return $next($request);
}else{
return redirect('admin/noaccess');
//需要自己写一个没有权限的页面noaccess
}
}
/跟Role的关联模型
public function role()
{
return $this->belongsToMany('App\Model\Role','blog_user_role','user_id','role_id');
}