Slim 3 实现路由过滤

Slim 3 Implement Route Filtering

我目前正在尝试在Slim 3中实现路由认证过滤,我想做的是:

$app->get("/route", Filter::$guest(), function ($request, $response, $args) {
... 
});

或者

$app->get("/route", function ($resquest, $response, $args) {

})->add(Filter::Admin);

过滤器 class 将是:

class Filter
{
    public static admin()
    {
        // Check if user is an admin.
        // If not, throw an Error
    }

...

在 Slim 2 中,我可以使用这样的东西

Filter.php

$authenticationCheck = function ($required) use ($app) {
    return function () use ($required, $app) {
        if ((!$app->auth && $required) || ($app->auth && !$required)) {
            $app->redirect($app->urlFor("home"));
        }
    };
};

$authenticated = function () use ($authenticationCheck) {
    return $authenticationCheck(true);
};

$guest = function () use ($authenticationCheck) {
    return $authenticationCheck(false);
};

$admin = function () use ($app) {
    return function () use ($app) {
        if (!$app->auth || !$app->auth->isAdmin()) {
            $app->notFound();
        }
    };
};

我可以做的路线:

$app->get("/route", $guest(), function () use ($app) {
    //Route
});

我知道我可以通过中间件获取路由,但我想不出一个很好的方法来区分 "admin" 路由和普通路由,而无需构建某种列表。

您可以创建一个基本的中间件 class Authorization:

<?php
class Authorization
{
    /**
     * Authorization middleware invokable class
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $request  PSR7 request
     * @param  \Psr\Http\Message\ResponseInterface      $response PSR7 response
     * @param  callable                                 $next     Next middleware
     *
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function __invoke($request, $response, $next)
    {
        $user = ""; //It should come from some place :)
        if(!$this->isAuthorized($user)){
          return $response->withRedirect('/notAuthorized');
        }
        return $next($request, $response);
    }

    /**
     * Check if the given user is authorized.
     *
     * @param  string $user The user to check.
     *
     * @return boolean True if the user is authorized, false otherwise.
     */
    protected function isAuthorized($user){
      return false;
    }
}

然后你可以扩展它并创建一个用于访客授权的中间件和另一个用于管理员授权的中间件:

<?php
class GuestAuthorization extends Authorization
{
  protected function isAuthorized($user){
    //Are you a guest?
    $isGuest = true; //Your magic business here
    return $isGuest;
  }
}

class AdminAuthorization extends Authorization
{
  protected function isAuthorized($user){
    //Are you an admin?
    $isAdmin = false; //Your magic business here
    return $isAdmin;
  }
}

让我们尝试一些路由并定义 notAuthorized 一个:

<?php

$app->get("/guestRoute", function ($resquest, $response, $args) {
  return $response->write("You're a guest");
})->add(new \GuestAuthorization());


$app->get("/adminRoute", function ($resquest, $response, $args) {
  return $response->write("You're an admin");
})->add(new \AdminAuthorization());

$app->get("/notAuthorized", function ($resquest, $response, $args) {
  return $response->write("You're not authorized for this, my son!");
});

专业人士:

  • 您可以用不同的方式处理每个角色的授权;
  • 您可以为单个路由添加多个中间件。

CON:

  • 你不能以这种方式处理动态角色;
  • 每个角色一个中间件。