PHP-Casbin 是一个非常流行的权限控制框架,支持ACL
RBAC
ABAC
等权限控制模型。
它使用 Matcher
中配置的表达式来做权限决策,不仅提供了非常多的内置函数,而且还可以在Matcher
中指定自定义函数。
安装
如果你的项目还有没有引入Casbin
依赖,则需要安装一下:
composer require casbin/casbin
决策器
这是演示的是纯原生PHP
代码,先初始化一个决策器Enforcer
。如果是在Laravel
、ThinkPHP
、Yii
等主流框架中,可以直接使用对应的扩展,拿到决策器的Facade
即可。
这里使用basic_model
作为演示:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
接着是实例化决策器:
<?php
require_once './vender/autoload.php';
use Casbin\Enforcer;
$enforcer = new Enforcer('path/to/basic_model.conf');
自定义函数
使用已经实例化的决策器Enforcer
,调用添加函数的方法,传入方法名和方法体即可。
假设,我们需要一个检查是否是超级管理员
的方法,在方法里实现,如果是超级管理就返回true
,在权限决策时,如果是超级管理员
,则需要放行所有权限。
那么,我们需要修改basic_model
中matchers
表达式:
[matchers]
m = checkIsAdmin(r.sub) || (r.sub == p.sub && r.obj == p.obj && r.act == p.act)
这里checkIsAdmin
就是一个自定函数,传入请求中的sub
参数,返回一个bool
结果。从上面的表达式m
中就可以看出,如果checkIsAdmin(r.sub)
返回true
,就不会执行后面的表达式,即达到了超级管理员
,则需要放行所有权限的要求。
接下来,就是来实现这个自定义函数checkIsAdmin
:
$enforcer->addFunction('checkIsAdmin', function(string $sub): bool {
// 假设如果传入的 sub 等于 root ,即认为是超级管理员
return $sub === 'root';
});
验证
上面我们添加了判断是否超级管理员
的自定义函数,这里来验证一下结果。
$res = $enforcer->enforce('aclie', 'data', 'read');
var_dump($res); // false
$res = $enforcer->enforce('root', 'data', 'read');
var_dump($res); // true
看到上面的验证,如果传入的第一个参数sub
是root
,就返回true
,就实现超级管理员
放行所有权限的要求。
最后
通过这个例子,主要介绍了在PHP-Casbin中通过自定义函数,实现不一样的权限决策逻辑。可以看出,这个自定义函数的功能还是非常实用的。当我们在实际项目中,遇到需要修改权限校验逻辑的时候,并不需要过多的侵入
已有的代码,就可以很方便的快速的做出修改。