主要记录自己开发过程中遇到的问题,记录下来,方便下次回顾
1.登录权限控制
首页在login时,需要将用户权限保存到ssession中,在使用的地方进行操作
一个问题 超级管理员 和普通管理员 怎么区分权限
首页创建一个 配置文件用来存放,是否是超级管理员,和不需要验证的公共权限 。
文件内容
<?php
return[
//超级管理员
'suepr'=>'admin',
//不验证的路由
'allow_route'=>[
'admin.index',
'admin.welcome',
'admin.getsysteminit',
],
];
定义超级管理员字段 ,设置不需要验证权限的菜单地址
2.登录获取当前用户权限 进行保存到sessio中
public function login(Request $request){
//表单验证
$validatedData = $request->validate([
'username' => 'required',
'password' => 'required',
]);
$bool = auth()->attempt($validatedData);
if($bool){
//判断 当前用户是否是 超级管理员 username 等于admin
if(config('rbac.suepr') == $validatedData['username']){
session(['admin.auth'=>true]);
//权限是true
}else{
//获取用户信息
$userModel = auth()->user();
//根据用户和角色表的关联模型 找到角色模型 信息
$roleModel = $userModel->role;
//根据角色模型 找对应的权限数据
$nodeData = $roleModel->nodes()->pluck('route_name','id')->toArray();
//最后将获取的权限信息 存到session
session(['admin.auth'=>$nodeData]);
}
return redirect(route("admin.index"));
}
return redirect(route("admin.login"))->withErrors(["error"=>"登录失败,账号密码不正确!"]);
}
在登录验证中 获取权限数据
3.中间件 验证路由是否 有权访问
创建一个新的中间件
Php artisan make:middleware CheckAadmin
修改Kernel,php 增加自定义验证的中间件
中间件使用在路由处
然后使用中间件进行验证
代码如下
/**
* Handle an incoming request.
*验证 登录权限
* @return mixed
*/
public function handle($request, Closure $next)
{
//传递参数 $param
//用户是否登录检查
if(!auth()->check()){
return redirect(route('admin.login'))->withErrors(['error'=>'请登录!']);
}
//权限判断 获取权限
$authRoute = session('admin.auth');
//如果是数组 就是普通管理员,不是数组则是超级管理员
if(is_array($authRoute)){
//路由权限控制 获取设置的权限
$authRoute =array_filter($authRoute);
//获取当前路由别名
$getRoute= $request->route()->getName();
//合并数组 将分配的权限和 不验证的权限 合并在一起
$Routes = array_merge($authRoute,config('rbac.allow_route'));
//用户访问路由 和 权限数组 进行 验证 是否存在 数组中
if(!in_array($getRoute,$Routes)){
exit("没有权限访问!");
}
}
//将验证成功的数组 保存到 request 中
$request->auths = $authRoute;
return $next($request);
}
下一步 验证路由地址是否 有权限访问,
首先 定义一个全局的类 进行操作
laravel 自定义类
1.在app 下面创建Helper 文件目录,然后在定义common文件
2.修改compser.json 文件
这个路径一定要写对,不然后面之前操作也报错
3.composer dump-autoload
执行命令
commo.php 文件具体写法
/**
* 验证按钮是否有权限
*/
function authBtn($route,$type,$title=0){
//判断 不是 超级管理员 并且 权限 存在
if((auth()->user()->username !== config('rbac.suepr')) && !in_array(request()->route()->getName(),request()->auths))
{
return "";
}
if($type=='delete'){
return ' <a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>';
}
if($type=='edit'){
return '<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="edit">编辑</a>';
}
return '<a class="layui-btn layui-btn-success layui-btn-xs data-count-edit" lay-event="'.$type.'">'.$title.'</a>';
}
页面调用 地方
{!! authBtn('admin.user.role','role','分配角色') !!}
{!! authBtn('admin.user.edit','edit') !!}
{!! authBtn('admin.user.del','delete') !!}
4,菜单 展示
// 获取菜单列表
private function getMenuList(){
return[
[
'title' => '后台管理',
'href' => '',
'icon' => 'fa fa-address-book',
'target' => '_self', //获取当前登录用户权限
'child' =>(new Node())->getMenuData(session('admin.auth'))
]
];
}
获取菜单列表 找到对应的权限 节点数据 getmenuData 是模型中操作的方法
/**
* 用户拥有权限
* $allow_node 可以拥有的权限
* @return
*/
public function getMenuData($allow_node){
//查询是否是菜单的 权限
$query = self::where('is_menu','1');
//判断是否是超级管理员 因为超级管理员是true
if(is_array($allow_node)){
//wherein 根据id 查询对应的 权限名称
$query->whereIn('id',array_keys($allow_node));
}
//取出符合条件的数据
$menuData = $query->select('id', 'name', 'pid','route_name')->get()->toArray();
//调用递归 层
return $this->getMenuTree($menuData);
}
getMenuTree 通过递归 获取 对应的层级菜单
//递归查询菜单
public function getMenuTree($data,$pid=0){
$arr =[];
foreach ($data as $value){
//给的pid 是当前父级 的id 进行循环
if($value['pid'] == $pid){
//子集 的夫id 是当前的id
$ar['title']=$value['name'];
$ar['href']= '';
if($value['route_name']){
$ar['href']= route($value['route_name']);
}
$ar['icon']=$this->icon();
$ar['target']="_self";
//子菜单
$ar['child']= $this->getMenuTree($data,$value['id']);
$arr[] = $ar;
}
}
return $arr;
}
权限控制 基本完成,以上是自己最近整理 的rbac权限控制。