使用两个三个表 user(用户) role(角色) rule(规则)
user 用户表:用户登录数据+用户所属的角色表中的ID
role 用户权限组表:角色的名称,规则的id
rule 规则表:规则名称,控制器名称,方法名称,启用状态
通过在数据库定义控制器,方法字段,通过Request参数判断当前访问的控制器名称,方法名称,将控制器,方法名称字段带入到数据库查询中查询取得这个操作的权限ID,再查询用户所拥有的权限组里面的rule字段,将这个字段使用explode方法转为数组,使用in_array()判断访问的这个方法的ID值是否存在用户组的权限rule字段里面
in_array(要搜索的值,待搜索的数组,搜索值是否需要全等(填写true、false))
//共三个参数
下面直接丢代码了
主要判断权限方法:
//文件是app\common.php 公共方法
<?php
use think\facade\Db; //数据库门面类,必须引入
use Firebase\JWT\JWT;//我使用jwt生成token的与本文无关
use think\facade\Request;//获取方法,控制需要的门面类
// 应用公共文件
function auth($id)
{
$controller = Request::controller();//获取访问的控制器名称
$action = Request::action();//获取访问的方法名称
$ruleid = Db::table('rule')->where('controller', $controller)->where('action', $action)->where('state', 1)->value('id'); //使用获取到的控制器名称和方法名称去查询这个权限的规则ID
$roleid = Db::table('user')->where('id', $id)->value('role');//取到用户的用户组ID
$role = Db::table('role')->where('id', $roleid)->value('rule');//查询用户组里面的规则ID字段
$rolearr = explode(",",$role);//将获取到的规则ID字段从字符串转为数组,转出来的格式为字符串
return in_array($ruleid,$rolearr);//输入 判断$ruleid(规则ID)是否在用户组所拥有的$role(规则ID数组)里面,没有使用第三个参数,使用了会判断全等,数组里面是字符串,获取的规则ID是int类型
}
使用这个方法判断:
<?php
declare(strict_types=1);
namespace app\controller;
use Exception;
use Throwable;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use app\BaseController;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\SignatureInvalidException;
class Token extends BaseController
{
/**
* Token验证
*/
// 验证 token
protected function initialize()
{
parent::initialize();
$header = request()->header();
if (!isset($header['token']) || $header['token'] == null) {
echo json(['code' => 0, 'msg' => 'token不能为空'], 400)->send();
die();
} else {
$token = $header['token'];
// 解密token
$key = 'Tokenpwd';
try {
$info = JWT::decode($token, new Key($key, 'HS256'));
//在这里判断,token验证正确后去访问这个方法,如果拥有权限auth($info->uid)输出true,否则false,if判断权限没问题就放行,否则提示权限不足中断操作
if (auth($info->uid)) {
$this->uid = $info->uid;
} else {
echo json(['status' => 400, 'msg' => '权限不足!'], 200)->send();
die();
}
} catch (SignatureInvalidException $e) { //签名不正确
echo json(['status' => 400, 'msg' => '签名不正确'], 400)->send();
die();
} catch (BeforeValidException $e) { // 签名在某个时间点之后才能用
echo json(['status' => 400, 'msg' => '账号未到可用时间'], 400)->send();
die();
} catch (ExpiredException $e) { // token过期
echo json(['status' => 400, 'msg' => '登录状态过期'])->send();
die();
} catch (Exception $e) { //其他错误
echo json(['status' => 400, 'msg' => '非法操作'], 400)->send();
die();
} catch (Throwable $e) {
echo json(['status' => 400, 'msg' => $e->getMessage()], 400)->send();
die();
}
}
}
}