TP5前后端分离RBAC权限管理API


坑神的博客文章可以参考,还可以和他交流请教,坑神人很nice!

1.后端

1.创建配置项目

1.创建项目
我用的是phpstudy和composer,在phpstudy的www目录下运行cmd,然后创建5.1的tp框架,创建名是rbac

composer create-project topthink/think=5.1.* rbac

2.设置项目

  1. 普通设置:'app_debug' => true, 'app_trace'=> true。这里我做API模块,所以方便起见可以设置默认入口文件。
  2. 数据库设置:database.php配置数据库信息。
  3. 域名设置:在phpstudy和hosts里面设置域名。
  4. 在项目目录下cmd:php think make:controller api/Login创建api模块下Login控制器。

2.管理员功能

2.1登录验证

1.首先前后端分离需要解决跨域问题,所以建一个Cross控制器,api控制器之后继承它。

php think make:controller api/Cross
<?php

namespace app\api\controller;

use think\Controller;
use think\Request;

class Cross extends Controller
{
    protected function initialize()
    {
        parent::initialize();
        header('Access-Control-Allow-Origin:*');
        header('Access-Control-Allow-Methods:GET, POST, OPTIONS,PUT, DELETE');
        header('Access-Control-Allow-Headers:Origin,X-Requested-With,Content-Type,token,Accept,x-access-sign,x-access-time');
        if (request()->isOptions()) {
            exit();
        }
    }
}

class Login extends Cross

2.jwt(JSON Web Token)登录
首先创建model

php think make:model AdminModel
<?php

namespace app\common\model;

use think\Model;

class AdminModel extends Model
{
    protected $table='admin';#表名
}

连接数据库表:在login的controller中

use app\common\model\AdminModel;
$db=new AdminModel();

引入JWT进行登录验证

composer require firebase/php-jwt
<?php

namespace app\api\controller;
use app\common\model\AdminModel;
use \Firebase\JWT\JWT;
use think\Controller;
use think\Request;

class Login extends Cross
{
    public function index(Request $request)
    {
        $data=$request->param();
        $db=new AdminModel();
        $info=$db->where('username',$data['username'])->find();
        if(!$info){
            return json(['code' => 0, 'msg' =>'账号不存在']);
        }
        if($info['password']!=$data['password']){
            return json(['code' => 0, 'msg' =>'账号或者密码不存在']);
        }
        $jwt=new JWT();
        $payload=[
            'iss'=>'rbac',
            'aud'=>'rbac',
            "iat" => time(),  // token 的创建时间
            "nbf" =>  time(),  // token 的生效时间
            "exp" => time() + 3600,  // token 的过期时间
            'aid'=>$info['id']
        ];
        $key='key';
        $keyId = "keyId";
        $token=$jwt::encode($payload,$key,"HS256",$keyId);
        // dump($token);
        return json(['code' => 1, 'msg' =>$token]);
    }

   
}

3.解析token

php think make:controller api/Base --plain#Base控制器只建一个初始化方法,然后这个Base类也要继承Cross实现跨域请求

这个算是一个中间件,初始化请求的token内容,从token里面获取uid信息。

<?php

namespace app\api\controller;

use think\Controller;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class Base extends Cross
{
    public function initialize()
    {
        parent::initialize();

        $header = request()->header();
        if (!isset($header['token'])){
            return json(['code'=>0,'msg'=>'请先登录'])->send();
        }
        if(empty($header['token'])){
            return json(['code'=>0,'msg'=>'请先登录'])->send();
        }
        $key = new Key('key', 'HS256');
        $info = JWT::decode($header['token'], $key);
        $this->aid=$info->aid;#token验证通过,将token里的uid拿到。
        // return json(['code'=>1,'token'=>$info])->send();
    }
}

4.请求路由控制器继承上面的base,就可以拿到用户id,然后进行权限验证

php think make:controller api/v1/Admin
<?php

namespace app\api\controller\v1;
use app\common\model\AdminModel;
use app\api\controller\Base;
use think\Request;

class Admin extends Base
{
   public function index()
   {
    $aid=$this->aid;
    $db=new AdminModel();
    $admininfo=$db->where('id',$aid)->find();#通过uid拿到这个用户的信息
    dump($admininfo);die();
   }
}

2.2.返回分页数据

通过$db->limit($limit)->page($page)->field($field)->select();即可获得指定页数据。

public function index(Request $request)
   {
    $limit=$request->param('limit')?$request->param('limit'):10;
    $page=$request->param('page')?$request->param('page'):1;
    $db=new AdminModel();
    $field='id,username,create_time';
    $list=$db->limit($limit)->page($page)->field($field)->select();
    if ($list){
        $count=$db->count('id');
        return json(['code'=>1,'msg'=>'获取成功','data'=>$list,'total'=>$count]);
    }else{
        return json(['code'=>0,'msg'=>'暂无数据']);
    }
   }

2.3增删改功能

public function save(Request $request)//修改和增加功能
   {
        $data=$request->param();
        // dump($data);die();
        $db=new AdminModel();
        if (isset($data['id']) && !empty($data['id'])){//有id,修改功能
            $info=$db->where('id',$data['id'])->find();
            // dump($info);die();
            if (isset($data['password'])&& !empty($data['password'])){//要修改密码
                if ($info['password']===md5($data['password'])){
                    $data['password']=$info['password'];
                }else{
                    $data['password']=md5($data['password']);
                }
            }
            $res=$db->save($data,['id'=>$info['id']]);//修改对象
        }else{//无id,添加功能
            $data['password']=md5($data['password']);//密码加密后再存到数据库
            $res=$db->save($data);//添加对象
        }
        if($res){
            return json(['code'=>1,'msg'=>'操作成功']);
        }else{
            return json(['code'=>0,'msg'=>'操作失败']);
        }
   }
   public function delete(Request $request)//删除功能
   {
        $id=$request->param('id');
        $db=new AdminModel();
        if ($id==1){//没有删除权限
            return json(['code'=>0,'msg'=>'此用户不能删除']);
        }
        $res=$db->where('id',$id)->delete();
        if ($res){
            return json(['code'=>1,'msg'=>'操作成功']);
        }else{
            return json(['code'=>0,'msg'=>'操作失败']);
        }
   }

3.角色功能

1.创建模型和控制器

php think make:controller api/v1/Role
php think make:model RoleModel

2.创建数据库并在模型里连接到数据库

<?php
namespace app\common\model;
use think\Model;
class RoleModel extends Model
{
    protected $table='role';
}

3.在controller里面写功能
3.1分页功能

public function index(Request $request)
    {
        $limit=$request->param('limit')?$request->param('limit'):10;
        $page=$request->param('page')?$request->param('page'):1;
        $db=new RoleModel();
        $list=$db->where('status',1)->limit($limit)->page($page)->select();
        if(!$list->isEmpty()){
            $count=$db->where('status',1)->count('id');
            return json(['code'=>1,'msg'=>'获取成功','data'=>$list,'total'=>$count]);
        }else{
            return json(['code'=>0,'msg'=>'暂无数据']);
        }
    }

3.2增删改功能

 public function save(Request $request)
    {
        if (!$request->isPost()){
            return json(['code'=>0,'msg'=>'操作失败']);
        }
        $data=$request->param();
        $db=new RoleModel();
        if(isset($data['id'])&&!empty($data['id'])){
            $res=$db->save($data,['id'=>$data['id']]);
        }else{
            $res=$db->save($data);
        }
        if ($res){
            return json(['code'=>1,'msg'=>'操作成功']);
        }else{
            return json(['code'=>0,'msg'=>'操作失败']);
        }
    }

    public function delete(Request $request)
    {
        $id=$request->param('id');
        $db=new RoleModel();
        $res=$db->where('id',$id)->delete();
        if ($res){
            return json(['code'=>1,'msg'=>'操作成功']);
        }else{
            return json(['code'=>0,'msg'=>'操作失败']);
        }
    }

3.权限管理

1.创建模型和控制器

php think make:controller api/v1/Rule
php think make:model RuleModel

2.创建数据库并在模型里连接到数据库

<?php
namespace app\common\model;
use think\Model;
class RuleModel extends Model
{
    protected $table='rule';
}

3.在controller里面写功能分页查询和增删改功能。

4.给管理员分配角色

1.创建模型(一对多的中间表)和控制器

php think make:controller api/v1/RoleAssign
php think make:model AdminRoleModel
<?php
namespace app\common\model;
use think\Model;
class AdminRoleModel extends Model
{
    protected $table='admin_role';
}

2.在控制器里进行增改查工作。

public function save(Request $request)//增改admin的role
    {
        $admin_id=$request->param('admin_id');
        $role_id=$request->param('role_id');
        $db=new AdminRoleModel();
        $info=$db->where('admin_id',$admin_id)->find();//如果admin——id存在就是修改用户角色表,否则是增加
        if($info){
            $res=$db->where('id',$info['id'])->setField('role_id',$role_id);
        }else{
            $data['admin_id']=$admin_id;
            $data['role_id']=$role_id;
            $res=$db->save($data);
        }
        if ($res){
            return json(['code'=>1,'msg'=>'操作成功']);
        }else{
            return json(['code'=>0,'msg'=>'操作失败']);
        }
    }

    public function read(Request $request)//根据id查看它的role有哪些
    {
        $admin_id=$request->param('admin_id');
        $db=new AdminRoleModel();
        $info=$db->where('admin_id',$admin_id)->find();
        $db=new RoleModel();
        $list=$db->where('status',1)->field('id,name')->select();
        if($info){
            $tmp=explode(',',$info['role_id']);#如果$info['role_id']的值为"1,2,3",那么$tmp的值就会是一个数组:["1", "2", "3"]
            foreach($list as $k=>$v){
                if(in_array($v['id'],$tmp)){
                    $list[$k]['check']=true;
                }else{
                    $list[$k]['check']=false;
                }
            }
        }else{
            foreach($list as $k=>$v){
                $list[$k]['check']=false;
            }
        }
        return json(['code'=>1,'data'=>$list]);
    }

5.给角色分配权限

1.创建模型(一对多的中间表)和控制器

php think make:controller api/v1/RoleRule
php think make:model RoleRuleModel
<?php
namespace app\common\model;
use think\Model;
class RoleRuleModel extends Model
{
    protected $table='role_rule';
}

2.在控制器里进行增改查工作(同上)。

<?php

namespace app\api\controller\v1;
use app\common\model\RuleModel;
use app\common\model\RoleRuleModel;
use think\Controller;
use think\Request;
use app\api\controller\Base;
class RoleRule extends Base
{
    public function index(Request $request)
    {
        $db=new RuleModel();
        $list=$db->where('status',1)->field('id,name')->select();
        return json(['code'=>1,'msg'=>'获取权限表','data'=>$list]);
    }
    public function save(Request $request)//增改role的rule
    {
        $role_id=$request->param('role_id');
        $rule_id=$request->param('rule_id');
        $db=new RoleRuleModel();
        $info=$db->where('role_id',$role_id)->find();//如果role——id存在就是修改用户角色表,否则是增加
        if($info){
            $res=$db->where('id',$info['id'])->setField('rule_id',$rule_id);
        }else{
            $data['role_id']=$role_id;
            $data['rule_id']=$rule_id;
            $res=$db->save($data);
        }
        if ($res){
            return json(['code'=>1,'msg'=>'操作成功']);
        }else{
            return json(['code'=>0,'msg'=>'操作失败']);
        }
    }

    public function read(Request $request)//根据id查看它的role有哪些
    {
        $role_id=$request->param('role_id');
        $db=new RoleRuleModel();
        $info=$db->where('role_id',$role_id)->find();
        $db=new RuleModel();
        $list=$db->where('status',1)->field('id,name,pid,img,url')->select();
        if($info){
            $tmp=explode(',',$info['rule_id']);#如果$info['rule_id']的值为"1,2,3",那么$tmp的值就会是一个数组:["1", "2", "3"]
            // dump($list);
            foreach($list as $k=>$v){
                if(in_array($v['id'],$tmp)){
                    $list[$k]['check']=true;
                }else{
                    $list[$k]['check']=false;
                }
            }
        }else{
            foreach($list as $k=>$v){
                $list[$k]['check']=false;
            }
        }
        return json(['code'=>1,'data'=>$list]);
    }
}

6.导航菜单功能(用户获取权限规则)

1.创建控制器

php think make:controller api/v1/Menu

2.在控制器里通过递归列表,拿到用户的所有权限

public function index()
    {
        $adminRole=new AdminRoleModel();
        $role_ids=$adminRole->where('admin_id',$this->aid)->value('role_id');#通过jwt验证后拿到用户的aid,然后通过aid拿到用户的所有role_id
        $role_ids_arr=explode(',',$role_ids);
        
        $roleRule=new RoleRuleModel();
        $roleRuleIds = $roleRule->whereIn('role_id', $role_ids_arr)->column('rule_id');#拿到每个role_id对应的rule_id
        $tmp='';
        foreach($roleRuleIds as $k=>$v){
            $tmp.=','.$v;
        }
        $tmps=substr($tmp,1);#将用户的所有rule_id放在列表里
        $rule=new RuleModel();
        $fields='id,name,img,pid,url';
        $list = $rule->whereIn('id', explode(',', $tmps))->field($fields)->select()->toArray();#拿到这个用户的每个rule的fileds信息
        $menus=$this->buildMenuTree($list);//用递归方法遍历,将一个扁平的列表转换成树状结构时
        return json(['code'=>1,'msg'=>'获取菜单成功','data'=>$menus]);
    }
    protected function buildMenuTree($list, $pid = 0)
    {
        $tree = [];
        foreach ($list as $item) {
            if ($item['pid'] == $pid) {
                $item['children'] = $this->buildMenuTree($list, $item['id']);
                $tree[] = $item;
            }
        }
        return $tree;
    }

2.前端

1.创建工程

vue create rbac_front
cd rbac_front
npm install axios
npm install element-plus
npm install vue-router
npm run serve
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是小z呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值