psecio/invoke

路由认证与授权管理

0.16.1 2018-08-18 17:40 UTC

This package is auto-updated.

Last update: 2024-09-15 10:25:23 UTC


README

Travis-CI Build Status Total Downloads Scrutinizer Code Quality

介绍视频

Route Protection with Invoke: Introduction

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]

继承

调用还包含继承的概念,允许评估规则的最终重用。这允许您设置一个您想要的路线,然后只需告诉其他路线继承它。

注意:这种继承是添加其他路线的检查,而不是替换

这使用inheritname关键字将路线匹配在一起。如果您没有为路线提供一个名称,则库无法进行继承匹配。

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();
}
?>