foothing/laravel-wrappr

将权限绑定到Laravel路由。

0.5.1 2017-06-26 18:06 UTC

This package is auto-updated.

Last update: 2024-09-22 23:19:22 UTC


README

Build Status Code Climate Test Coverage

对于Laravel 5.1,请使用0.4.10版本

对于Laravel 5.2及以上版本,请使用最新的0.x版本

这是一个旨在简化将路由绑定到权限过程的Laravel 5包,它独立于特定的权限处理器,即使您的权限处理器不支持此功能,也允许添加路由检查。

此外,它还试图在基本操作方面将您的应用程序与权限处理器解耦。

有一个锁定集成可立即使用。

我还计划实现一个Gate集成,如果您对此感兴趣,请随时留言。

用法示例

在您想要限制路由访问到read.users权限的基本用例中

Route::get('api/users/{id?}', ['middleware:wrappr.check:read.users,user,{id}', function() {
	// Access is allowed to users with the 'read.users' permission on
	// the 'user' resource with the {id} identifier
}]);

或者,您可以为动态URL定义自定义路由模式,前提是您已经定义了控制器,并希望在方法上分割访问逻辑。

Route::controller('api/v1/{args?}', 'FooController');

假设您的控制器提供了以下路由

GET /api/v1/resources/users
GET /api/v1/resources/posts
POST /api/v1/services/publish/post

您可以定义如下规则来限制访问

[
	'verb' => 'put',
	'path' => 'api/v1/resources/posts/{id}',
	'permissions' => ['posts.create', 'posts.update'],
	'resource' => 'post',
],

内容

概念

由于您可能需要在某个时候切换到另一个acl库,因此我已经努力添加了一个抽象层,可以使您的应用程序更容易维护。此包试图以两种不同的方式抽象您的应用程序与acl层

  • 基于路由的检查标准方法
  • 基本acl操作的标准API

为了访问权限检查,必须设置一个充当acl库桥接器的权限提供者。此外,还需要一个用户提供者来检索认证用户。

虽然路由检查是这个项目的重点,但acl操作功能尽量不干涉,您可以随意使用它。

安装和设置

Composer安装

"require": [
	"foothing/laravel-wrappr": "0.*"
]

在您的config/app.php提供者数组中添加服务提供者。

'providers' => [
	// ...
	Foothing\Wrappr\WrapprServiceProvider::class
]

然后发布包配置和迁移文件

php artisan vendor:publish --provider="Foothing\Wrappr\WrapprServiceProvider"

配置提供者

发布配置文件后,您可以根据项目设置配置一个用户提供者和一个权限提供者。此示例配置将启用与LockIlluminate\Auth\Guard的集成。

在您的config/wrappr.php

'permissionsProvider' => 'Foothing\Wrappr\Lock\LockProvider',
'usersProvider' => 'Foothing\Wrappr\Providers\Users\DefaultProvider',

在Laravel路由器中使用

此包有两种用法,每种用法都由自己的中间件实现。让我们看看默认情况。首先,您需要设置中间件在您的App\Http\Kernel中。

添加以下行

protected $routeMiddleware = [
	'wrappr.check' => 'Foothing\Wrappr\Middleware\CheckRoute',
];

使用CheckRoute中间件来控制对以下routes.php中的路由的访问

Route::get('api/users', ['middleware:wrappr.check:admin.users', function() {
	// Access is allowed for the users with the 'admin.users' permission
}]);

CheckRoute中间件接受3个参数

  • 所需权限
  • 可选的资源名称,例如“user”
  • 一个可选的资源标识符(整数)

示例

Route::get('api/users/{id?}', ['middleware:wrappr.check:read.users,user,1', function() {
	// Access is allowed for the users with the 'read.users' permission on
	// the 'user' resource with the {id} identifier
}]);

此外,中间件可以处理您的路由参数。请考虑以下内容

Route::get('api/users/{id?}', ['middleware:wrappr.check:read.users,user,{id}', function() {
	// Access is allowed for the users with the 'read.users' permission on
	// the 'user' resource with the {id} identifier
}]);

当您在括号内传递资源标识符时,中间件将自动尝试从HTTP请求中检索值。

与自定义路由一起使用

当您无法在路由定义级别精细控制时,有另一种处理权限的方法。考虑以下全局RESTful控制器

Route::controller('api/v1/{args?}', 'FooController');

假设您的控制器使用变量模式来处理路由,例如

GET /api/v1/resources/users
GET /api/v1/resources/posts
POST /api/v1/services/publish/post

在这种情况下,您无法使用先前的方法绑定权限,因此CheckPath中间件可以提供帮助。为了启用此行为,您需要执行一些额外的设置步骤。

第一步是运行您之前发布的迁移。

php artisan migrate

然后您有两个选择。

使用配置文件安装路由

现在您可以在您的config/wrappr.php中配置您想要置于授权控制下的路由,编辑您的routes部分

'routes' => [

	[
		// Allowed values are 'get', 'post', 'put', 'delete'
		// or the '*' wildcard to enable all verbs.
		'verb' => 'post',

		// The url path we want to restrict access to.
		'path' => 'foo',

		// The required permissions for the given path.
		'permissions' => 'bar',
	],

	// This configuration will control the access to the
	// POST:api/v1/resources/users action, which will be
	// only allowed for users with the 'admin.account' permission
	[
		'verb' => 'post',
		'path' => 'api/v1/resources/users',
		'permissions' => 'admin.account',
	],


	// This configuration will control the access to the
	// PUT:api/v1/resources/posts/{id} action, which will be
	// only allowed for users with both the 'posts.create' and
	// 'posts.update' permissions on the 'post' resource with
	// the {id} identifier.
	[
		'verb' => 'put',
		'path' => 'api/v1/resources/posts/{id}',
		'permissions' => ['posts.create', 'posts.update'],
		'resource' => 'post',
	],

	// In this case the 'admin/' nested routes
	// will be granted access only when the 'admin' permission
	// is available to the current auth user.
	[
		'verb' => '*',
		'path' => 'admin/*',
		'permissions' => ['admin'],
	],

	// You can also use the path wildcard in this way,
	// therefore requiring the 'superadmin' permission
	// for each route starting with 'admin'.
	[
		'verb' => '*',
		'path' => 'admin*',
		'permissions' => ['superadmin'],
	],
],

完成路由设置后,运行Artisan命令

php artisan wrappr:install

请注意,每次您更改路由配置时,都应在Artisan命令中再次运行以刷新它们。

程序化安装路由

或者,您可以使用RouteInstaller来程序化设置您的路由。在这种情况下,您不需要Artisan命令。

$installer = \App::make('foothing.wrappr.installer');
$installer
	->route('get', '/api/v1/*')->requires('api.read')
	->route('put', '/api/v1/*')->requires('api.write')
	->route('delete', '/api/v1/users/{id}/*')->requires('api.write,api.read')->on('users')
	->install();

// Use wildcard
$installer->route('*', '/admin')->requires->('admin.access');

设置中间件

将全局中间件添加到您的App\Http\Kernel中,如下所示

protected $middleware = [
	\Foothing\Wrappr\Middleware\CheckPath::class
];

然后您就设置好了。

关于路由处理顺序的说明

中间件将解析所有传入的HTTP请求以匹配您安装的路由,并且将做出如下反应

  • 如果找不到路由模式,则访问被允许
  • 如果找到路由模式,它将触发权限提供者以执行检查

一旦您安装了路由,请记住,它们将按层次顺序处理,从更具体的到更通用的。看以下示例

api/v1/users/{id}/*
api/v1/users/{id}
api/v1/*
api/v1
api/*

这会导致以下行为

  • 如果您请求foo/bar路由未找到,因此访问被允许
  • 如果您请求api/foo,则绑定到api/*模式的权限将被应用
  • 如果您请求api/v1,则绑定到api/v1模式的权限将被应用

依此类推。

中间件响应

这两个中间件实现都会在失败时返回HTTP 401,并带有额外的X-Reason: permission头部,这对于处理客户端的响应(例如,一个Angular拦截器)非常有用。

如果您希望中间件检查失败时错误响应被重定向,只需在您的wrappr.config中设置重定向路径即可

'redirect' => '/login'

当HTTP请求是Ajax请求时,此值将被忽略。

如何开发提供者

扩展Foothing\Wrappr\Providers\Permissions\AbstractProvider

您需要实现强制性的check()方法,并且您可以选择实现或忽略其他可选方法。

/**
 * Check the given user has access to the given permission.
 *
 * @param      $user
 * @param      $permissions
 * @param null $resourceName
 * @param null $resourceId
 *
 * @return mixed
 */
public function check($user, $permissions, $resourceName = null, $resourceId = null);

/**
 * Check the given subject has access to the given permission.
 *
 * @param      $permissions
 * @param null $resourceName
 * @param null $resourceId
 *
 * @return mixed
 */
public function can($permissions, $resourceName = null, $resourceId = null);

/**
 * Fluent method to work on users.
 * @param $user
 * @return self
 */
public function user($user);

/**
 * Fluent method to work on roles.
 * @param $role
 * @return self
 */
public function role($role);

/**
 * Return all permissions for the given subject.
 * @return mixed
 */
public function all();

/**
 * Grant the given permissions to the given subject.
 *
 * @param      $permissions
 * @param null $resourceName
 * @param null $resourceId
 *
 * @return mixed
 */
public function grant($permissions, $resourceName = null, $resourceId = null);

/**
 * Revoke the given permissions from the given subject.
 *
 * @param      $permissions
 * @param null $resourceName
 * @param null $resourceId
 *
 * @return mixed
 */
public function revoke($permissions, $resourceName = null, $resourceId = null);

许可证

MIT