I am creating middleware for auth into REST API. My API is created using Slim PHP Framework ,which in case provide great features to build APIs. One of this feature is Middleware.
I need to check credentials in Middleware and respond with an error (HTTP code with JSON descriptions) to the user.
But unfortunatly Slim Framework gives me an exception whenever I try to halt and respond with the HTTP code.
<?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();
}
}
respondWithHttpStatus method uses slim framework method $app->halt($code, $response);
In this case when I try to execute this method I get an Exception from
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
How to deal with this problem.
My goal is to control user credentials in middleware and if it is something wrong respond with the appropriate HTTP code and JSON message describing the reason of the error.
Maybe it is better to follow another way.
Please suggest.
ONE POSSIBLE WORKAROUND
$app->response->setStatus(400);
$app->response->headers->set('Content-Type', 'application/json');
print Response::respondWithHttpStatus($app,400,false);
And respond function
public static function 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;
}
}
For my needs suits well, also throwing an exception can be another solution but in my case I don't need to continue, just setting header, code and don't call next - works for me.