[PHP-Casbin](https://github.com/php-casbin/php-casbin) 是一個強大的、高效的開源訪問控制框架,它支持基于各種訪問控制模型的權限管理。
[Slim](http://slimframework.com) 是一個PHP微框架,可幫助您快速編寫簡單但功能強大的Web應用程序和API。
[Casbin](https://github.com/php-casbin/php-casbin) 可用作 Slim Framework 中的一個`授權`中間件。
### 認證
先認證,后授權。
這里我們使用 [HTTP Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication).
[slim-basic-auth](https://github.com/tuupola/slim-basic-auth) 提供了 PSR-7 和 PSR-15 基本身份驗證中間件,您可以使用composer進行安裝: `composer require tuupola/slim-basic-auth`。
```php
$app->add(new HttpBasicAuthentication([
'users' => [
'root' => 't00r',
'somebody' => 'passw0rd',
],
'before' => function ($request, $arguments) {
return $request->withAttribute('user', $arguments['user']);
},
]));
```
### Casbin 授權中間件
本示例實現了授權中間件。
它首先獲取當前已認證的`user`,當前請求的`uri`和`method`,然后使用`Casbin` 去權限決策。
```php
namespace App\Middleware;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
use Casbin\Enforcer;
class Authorization
{
/**
* Authorization middleware invokable class.
*
* @param ServerRequest $request PSR-7 request
* @param RequestHandler $handler PSR-15 request handler
*
* @return Response
*/
public function __invoke(Request $request, RequestHandler $handler): Response
{
$e = new Enforcer('config/rbac_model.conf', 'config/policy.csv');
$user = $request->getAttribute('user');
$uri = $request->getUri();
$action = $request->getMethod();
if ($user && !$e->enforce($user, $uri->getPath(), $action)) {
$response = new Response();
$response->withStatus(403)->getBody()->write('Unauthorized.');
return $response;
}
$response = $handler->handle($request);
return $response;
}
}
```
Model文件`config/rbac_model.conf` 內容如下:
```
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act
```
策略文件`config/policy.csv`內容如下:
```
p, root, /, GET
p, root, /users, GET
p, root, /users/:id, GET
```
### 創建路由
```php
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write('Hello Casbin !');
return $response;
});
$app->group('/users', function (Group $group) {
$group->get('', ListUsersAction::class);
$group->get('/{id}', ViewUserAction::class);
});
```
### Casbin 骨架應用
完整的代碼 : [Casbin skeleton application with Slim Framework 4](https://github.com/php-casbin/casbin-with-slim).
它讓使用 Slim Framework 4 配置新的 `Casbin` 骨架應用程序變得容易快捷。