如何在中间件Slim PHP框架中响应

4 php authentication rest middleware slim

我正在为REST API创建用于身份验证的中间件。我的API是使用Slim PHP Framework创建的,以防提供构建API的强大功能。此功能之一是中间件。
我需要检查中间件中的凭据,并向用户响应一个错误(带有JSON描述的HTTP代码)。
但是不幸的是,每当我尝试停止并使用HTTP代码进行响应时,Slim Framework都会给我一个例外。

<?php
require_once __DIR__.'/../Slim/Middleware.php';
class TokenAuth extends \Slim\Middleware {
    private $auth;
    const SECURED_URI_REGEX = "/^\/v\d\/store\/(orders|users|payment).*/";
    const TOKEN_PARAMETER = "token";
    const USER_EMAIL_PARAMETER = "user_email";
    public static $credentialsArray = array(TokenAuth::TOKEN_PARAMETER,TokenAuth::USER_EMAIL_PARAMETER);
    public function __construct() {  
    }
    public function deny_access() {
       print Response::respondWithHttpStatus($app,401,true);
    }
    public function call() {
         $app = $this->app;  
        $uri = $app->request->getResourceUri();
        if (preg_match(TokenAuth::SECURED_URI_REGEX, $uri)) {
             $tokenAuth = $app->request->headers->get('Authorization'); 
             if(isset($tokenAuth)) {
             $parsedCredentials = TokenAuth::parseAndValidateCredentials($tokenAuth); 
             if (!$parsedCredentials) {
                 Response::respondWithHttpStatus($app,401,true);
             }
             else {
                $auth = new Authenticator($parsedCredentials[TokenAuth::USER_EMAIL_PARAMETER],$app);
                print $auth->userHasToken();
             }
         }
         else {
             Response::respondWithHttpStatus($app,400,true);
         }
        }
        else {
             $this->next->call();
        }

    }
Run Code Online (Sandbox Code Playgroud)

responseWithHttpStatus方法使用苗条的框架方法 $ app-> halt($ code,$ response);

在这种情况下,当我尝试执行此方法时,会从

Slim Framework 
The application could not run because of the following error:

Details

Type: Slim\Exception\Stop
File: /var/www/api/Slim/Slim.php
Line: 1022
Run Code Online (Sandbox Code Playgroud)

如何处理这个问题。
我的目标是控制中间件中的用户凭据,如果有问题,请使用适当的HTTP代码和描述错误原因的JSON消息进行响应。
也许最好走另一条路。
请提出建议。

一个可能的解决方法

   $app->response->setStatus(400);
   $app->response->headers->set('Content-Type', 'application/json');
   print Response::respondWithHttpStatus($app,400,false);
Run Code Online (Sandbox Code Playgroud)

并响应功能

公共静态函数basicRespond($ app,$ code,$ message,$ halt){

    if(!isset($message) || empty($message)) {
        $message = Response::$RESPONSE_MAP[$code];
    }
    $response = json_encode($message);
    if($halt===true) {
        $app->halt($code, $response);
    }
    else {
        return $response;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于我的需求而言,也可以抛出异常是另一种解决方案,但就我而言,我不需要继续,只需设置标头,代码并且不调用next-对我来说就可以了。

ale*_*exw 5

您不能halt在中间件中使用:

/sf/answers/714111681/

暂停只能在路由回调的上下文中调用。

相反,您可以400使用PHP header和手动生成响应exit

header("HTTP/1.1 400 Access denied");
exit;
Run Code Online (Sandbox Code Playgroud)

或者,

您可以定义一种新的Exception类型:

class AuthException extends Exception {
    public function __construct() {
        $message = 'You must authenticate to access this resource.';
        $code = 400;
    }
}
Run Code Online (Sandbox Code Playgroud)

赶上您的error路线:

$app->error(function (\Exception $e) use ($app) {
    // Example of handling Auth Exceptions
    if ($e instanceof AuthException) {
        $app->response->setStatus($e->getCode());
        $app->response->setBody($e->getMessage());
    }
});
Run Code Online (Sandbox Code Playgroud)

AuthException在拒绝授权时抛出:

throw new AuthException();
Run Code Online (Sandbox Code Playgroud)

本质上,这就是在Slim-Auth中完成的方式