从Slim路线中排除中间件

时间:2016-10-25 11:13:32

标签: php slim

http://www.slimframework.com/docs/concepts/middleware.html,可以将中间件添加到应用程序,路由或组。

如何将中间件添加到所有路由(即应用程序),但是将其从特定路由中排除?

EDIT。作为一种可能的解决方案,我正在考虑在我的应用程序中间件中添加一些逻辑来绕过中间件功能。使用$request->getMethod()很容易获得该方法,但是http://www.slimframework.com/docs/objects/request.html描述的其他URL方法在中间件中不可用。

4 个答案:

答案 0 :(得分:1)

我认为您需要将中间件添加到路由组,示例管理路由组和用户组。 如果您想要更改动态行为,您必须修改中间件逻辑以检查您的特定请求, 如果客户端设置了请求类型,则路由示例返回JSON。

修改

$app = new \Slim\App();

//pass $app to middleware
$app->add(function ($request, $response, $next) use ($app) {
    //do what you want with $app.
    //reads config file with routes for exclude  
    $response = $next($request, $response);
    return $response;
});

$app->get('/', function ($request, $response, $args) {
    $response->getBody()->write(' Hello ');

    return $response;
});

$app->run();

答案 1 :(得分:1)

您可以使用以下内容访问中间件中的uri。

$uri = $request->getUri()->getPath();

如果$uri匹配您要从中间件中排除的路径,则可以使用该信息提前从中间件返回。

答案 2 :(得分:0)

如果您想添加全局中间件,最简单的方法是实现以下目标。

$app->group('', function () {

   //Add your routes here, note that it is $this->get() ... etc inside the closure

})->add(MyNewMiddlewareClass::class);

答案 3 :(得分:0)

我相信,在撰写本文时(我正在使用Slim 3.12.1),您的问题的答案是无法从路线中删除以前添加的中间件。< / p>

accepted answer建议的解决方案使中间件实现与路由定义紧密结合。如果路由(或在similar suggested solution中的路由名称)更改,则中间件代码也需要更改。这是因为从技术上说,中间件没有从路由中间件堆栈中被删除。在某些情况下,这变得很复杂。例如,如果中间件是别人编写的。您可能希望避免更改第三方库的代码,因此最终可能会扩展第三方中间件以某种方式或某种类似的解决方案覆盖其功能,而则会使实现与您的路线相结合定义

我的建议是,不要更改中间件的逻辑以阻止某些路由执行它,而是向代码中添加逻辑以控制哪些中间件应添加到哪些路由。该功能示例演示如何在所有路由中添加通用中间件,而仅在某些特定路由中而不是全部(您要排除的路由)中添加一些中间件。为了简单起见,没有逻辑来确定应将哪些中间件添加到哪些路由,但这证明了基本思想。假设如下:

    /user开头的
  • 路径应受Authorization中间件保护
  • /user/login/user/signup是例外,不需要受Authentication中间件的保护。相反,我们只允许尝试从特定IP地址进行登录/注册,因此我们需要使用IP Access Control中间件
  • 保护此路由。
  • 对以/user开头的所有路径的所有请求均应使用Logger中间件记录(此处无例外)
  • 其他路由不需要任何中间件(因此我们应避免使用$app->add()
<?php
require __DIR__ . '/../vendor/autoload.php';

$app = new Slim\App;

// A simple middleware to write route path and middleware name
class SampleMiddleware
{
    public function __construct($name)
    {
        $this->name = $name;
    }
    public function __invoke($request, $response, $next)
    {
        $response->write($request->getUri()->getPath() . ' invokes ' . $this->name . "\n");
        return $next($request, $response);
    }
}
// Three middleware instances with different names
$auth = new SampleMiddleware('Authorization');
$ipAC = new SampleMiddleware('IP Access Control');
$logger = new SampleMiddleware('Logger');

$group = $app->group('/user', function($app) {
    $app->get('/profile', function($request, $response, $args){
        return $response;
    });
    $app->get('/messages', function($request, $response, $args){
        return $response;
    });
})->add($auth)
  ->add($logger);

$group = $app->group('/user', function($app) {
    $app->get('/login', function($request, $response, $args){
        return $response;
    });
    $app->get('/signup', function($request, $response, $args){
        return $response;
    });
})->add($ipAC)
  ->add($logger);

$app->get('{p:.*}', function($request, $response, $args){
    $response->write('No middleware for ' . $request->getUri()->getPath());
    return $response;
});

$app->run();

输出:

/用户/个人资料

  

/ user / profile调用Logger
  / user / profile调用授权

/用户/登录

  

/ user / login调用Logger
  / user / login调用IP访问控制

/其他/其他

  

没有用于/ something / else的中间件