psecio / invoke
路由认证与授权管理
Requires
- php: >=5.4.0
- symfony/yaml: ^4.1
Requires (Dev)
- phpunit/phpunit: ^5.3
README
介绍视频
Invoke系统帮助您根据端点和请求的URI来保护您的应用程序。它使用配置文件(或设置数组)来定义请求资源所需的权限。例如,它可以让您定义如下内容:
"对于这个端点,我只允许拥有名为'test'的组的认证用户通过"。
目前,Invoke将所有标准视为AND,因此它们必须满足所有标准才能通过验证。
使用示例
<?php $en = new \Psecio\Invoke\Enforcer(__DIR__.'/config/routes.yml'); $allowed = $en->isAuthorized( new InvokeUser(array('username' => 'ccornutt')), new \Psecio\Invoke\Resource() ); if ($allowed === true) { echo 'Good to go!'; } ?>
在这种情况下,我们传入一个实现了\psecio\invoke\UserInterface的InvokeUser类实例,以实现一致的用户处理。该类定义了三个方法
getGroups
用于返回InvokeGroup对象实例的集合getPermissions
isAuthed
用于确定用户是否已认证
这些方法应该在您的类中实现以返回相同的值。这是您所使用的用户系统与Invoke检查之间的“桥梁”。
InvokeGroup类应实现\psecio\invoke\GroupInterface并应具有以下方法
getName
用于返回组的字符串名称getPermissions
Invoke工具假设典型的RBAC组/权限设置,但它可以直接用于确定用户的权限。因此,在\psecio\invoke\PermissionInterface中还有一个权限接口,其中有一个方法
getName
用于返回当前权限的“名称”
可选,您可以直接在InvokeUser对象上实现getPermissions和getGroups方法,而不是返回InvokePermission和InvokeGroup的集合。这将大大简化流程并减少您需要实现的开销。例如,您不必创建权限类并返回实例
<?php class MyGroup implements \Psecio\Invoke\GroupInterface { } class MyUser implements \Psecio\Invoke\UserInterface { public function getGroups() { return [ new MyGroup(), new MyGroup() ]; } } ?>
配置
配置基于YAML格式的文件。以下是一个示例结构
event/add: protected: on groups: [test] permissions: [testperm1]
在这个示例中,我们告诉系统,/event/add路由应该受到保护(只允许认证用户),并且需要用户拥有名为“test”的组和用户权限“testperm1”。系统将接收此配置,并在Enforcer内部自动解析和处理。
路由可以是简单的匹配,也可以是更复杂的正则表达式。例如,如果我们只想匹配前往我们的/event/view页面的具有数字ID的URL,我们可以使用
event/view/([0-9]+): protected: on groups: [test] permissions: [testperm1] methods: [get, post]
这将匹配类似/event/view/1的URL,但不能匹配/event/view/foo。路由本身实际上是一个正则表达式。如果您熟悉正则表达式,您也会注意到我们的示例中有捕获括号。这些可以用于从匹配实例中收集匹配数据
<?php $config = array('/event/view/([0-9]+)'); $uri = '/event/view/1234'; $matcher = new \Psecio\Invoke\Match\Route\Regex($config); if ($matcher->evaluate($uri) === true) { $params = $matcher->getParmas(); } ?>
这将返回以下内容在$params
Array (
[0] => /event/view/1234
[1] => 1234
)
此外,路由还支持使用占位符和参数进行额外检查的概念。要使用这些占位符,您在路径中使用冒号表示法,然后在主体中的params检查中引用它们。例如,假设您只想匹配ID为5的活动
event/view/:id: protected: on params: [id:5]
继承
调用还包含继承的概念,允许评估规则的最终重用。这允许您设置一个您想要的路线,然后只需告诉其他路线继承它。
注意:这种继承是添加其他路线的检查,而不是替换。
这使用inherit
和name
关键字将路线匹配在一起。如果您没有为路线提供一个名称,则库无法进行继承匹配。
event/admin: protected: on groups: [group1] name: event-add event/add: inherit: event-add
因此,在这个例子中,我们告诉Invoke,当用户访问event/add
端点时,我们希望将event/admin
的所有检查添加到其中。在这种情况下,只是端点是受保护的,并且它们属于“group1”组。
因此,如果用户来到/event/view/5
(并且已经登录),这个路由将匹配,并且isAuthorized
调用将返回true
。
匹配类型
目前,Invoke系统中有一些匹配类型可用于评估:路由匹配、组检查和权限检查。您不需要做任何外部操作来使用这些匹配 - 它们是从配置文件为您生成的。
Match/User/HasGroup
Match/User/HasPermission
Match/Route/Regex
Match/Route/HasParameters
Match/Resource/HasMethod
Match/Resource/IsProtected
Match/Object/Callback
还将有更多这样的匹配类型出现...所以请保持关注。
回调匹配
callback
匹配类型允许您直接调用自己的类和方法,并评估检查的结果。该方法应返回一个boolean
值。为了正确调用,方法应定义为静态。例如
event/view/:id: protected: on callback: \App\MyUser::checkAccess
然后,在您的类中
<?php namespace App; class MyUser { public static checkAccess($data) { $result = false; /* return the result of the evaluation */ return $result; } } ?>
回调应接受一个参数,即$data
值,它是\Psecio\Invoke\Data
的实例。该对象允许您访问
- 当前用户(
\Psecio\Invoke\InvokeUser
) - 请求的资源(
\Psecio\Invoke\Resource
) - 匹配的路由(
\Psecio\Invoke\RouteContainer
)
这三样东西提供了您评估请求所需的环境。这些信息可以通过分别通过$data->user
、$data->resource
和$data->route
属性访问。
失败
如果isAuthorized
调用的结果为false
,您可以查询该对象以获取第一个失败的匹配的错误消息
<?php $en = new \Psecio\Invoke\Enforcer(__DIR__.'/config/routes.yml'); $allowed = $en->isAuthorized( new InvokeUser(array('username' => 'ccornutt')), new \Psecio\Invoke\Resource() ); if ($allowed === false) { echo 'ERROR: '.$en->getError(); } ?>