Slim 4中的路由中间件不会停止调用路由中的可调用对象 [英] Route Middleware in Slim 4 doesn't stop invoking the callable in the route

查看:289
本文介绍了Slim 4中的路由中间件不会停止调用路由中的可调用对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Slim4中的授权中间件.这是我的代码:

I'm strugling with authorization middleware in Slim4. Here's my code:

$app = AppFactory::create();
$app->add(new Authentication());

$app->group('/providers', function(RouteCollectorProxy $group){
    $group->get('/', 'Project\Controller\ProviderController:get');
})->add(new SuperuserAuthorization());

身份验证中间件检查用户并正常工作.

Authentication middleware checks the user and works fine.

ProviderController中的方法 get

The method get in ProviderController is

public function get(Request $request, Response $response): Response{
    $payload = [];
    foreach(Provider::all() as $provider){
        $payload[] = [
            'id' => $provider->id,
            'name' => $provider->name,
        ];
    }
    $response->getBody()->write(json_encode($payload));
    return $response;
}

SuperuserAuthorization看起来像这样

The SuperuserAuthorization looks like this

class SuperuserAuthorization{
    public function __invoke(Request $request, RequestHandler $handler): Response{
        $response = $handler->handle($request);
        $authorization = explode(" ", $request->getHeader('Authorization')[0]);
        $user = User::getUserByApiKey($authorization[1]);
        if(! Role::isSuperuser($user)){
            return $response->withStatus(403);//Forbidden
        }
        return $response;
    }
}

问题是,即使用户不是超级用户,应用程序仍会继续执行.结果,我得到所有提供者的json和http代码403:/

The thing is that even though the user is not a superuser, the application continues executing. As a result I get json with all the providers and http code 403 :/

路由中间件不会阻止请求进入应用程序,而立即返回403吗?

Shouldn't route middleware stop the request from getting into the app and just return 403 right away?

我知道我可以创建状态为403的新的空响应,因此数据不会出来,但要点是请求永远都不应超出此中间件,是对还是我只是误解了这里……

I know that I can create new empty response with status 403, so the data won't come out, but the point is that the request should never get beyond this middleware, am I right or did I just misunderstand something here…

任何帮助将不胜感激:)

Any help will be appreciated :)

-------------解决方案----------------

------------- SOLUTION ----------------

感谢@Nima,我解决了它.中间件的更新版本为:

Thanks to @Nima I solved it. The updated version of middleware is:

class SuperuserAuthorization{
    public function __invoke(Request $request, RequestHandler $handler): Response{
        $authorization = explode(" ", $request->getHeader('Authorization')[0]);
        $user = User::getUserByApiKey($authorization[1]);
        if(! Role::isSuperuser($user)){
            $response = new Response();
            return $response->withStatus(403);//Forbidden
        }
        return $handler->handle($request);
    }
}

推荐答案

路由中间件不会阻止请求进入应用程序,而立即返回403吗?

Shouldn't route middleware stop the request from getting into the app and just return 403 right away?

Slim 4使用 PSR-15 兼容中间件. 示例在PSR-15元文档中实现授权中间件.如果您不希望进一步处理请求,则需要避免调用$handler->handle($request).

Slim 4 uses PSR-15 compatible middlewares. There is good example of how to implement an authorization middleware in PSR-15 meta document. You need to avoid calling $handler->handle($request) if you don't want the request to be processed any further.

如果请求未被授权,则返回与$handler->handle($request)的返回值不同的响应.这意味着您要说的是:

As you can see in the example, if the request is not authorized, a response different from the return value of $handler->handle($request) is returned. This means your point saying:

我知道我可以创建状态为403的新的空响应,因此数据不会出来,但要点是,请求永远都不能超出中间件

I know that I can create new empty response with status 403, so the data won't come out, but the point is that the request should never get beyond this middleware

在某种程度上是正确的,但是应该通过在调用处理程序之前返回适当的响应 或引发异常并让错误处理程序处理它,以防止请求进一步处理

is somehow correct, but you should prevent the request from going further by returning appropriate response before invoking the handler, or throwing an exception and let the error handler handle it.

这是一个简单的中间件,它随机授权一些请求,并为其他请求抛出异常:

Here is a simple middleware that randomly authorizes some of requests and throws an exception for others:

$app->group('/protected', function($group){
    $group->get('/', function($request, $response){
        $response->getBody()->write('Some protected response...');
        return $response;
    });
})->add(function($request, $handler){
    // randomly authorize/reject requests
    if(rand() % 2) {
        // Instead of throwing an exception, you can return an appropriate response
        throw new \Slim\Exception\HttpForbiddenException($request);
    }
    $response = $handler->handle($request);
    $response->getBody()->write('(this request was authorized by the middleware)');
    return $response;
});

要查看不同的响应,请几次访问/protected/路径(记住中间件是随机运行的)

To see different responses, please visit /protected/ path a few times (remember the middleware acts randomly)

这篇关于Slim 4中的路由中间件不会停止调用路由中的可调用对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆