We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Return 401 status code in micro app using or event manager

So i am having some trouble with this.

I am making an authed REST api using the micro app.

In looking at the docuementation Here it looks like the easiest way to implement the auth woudl be to use the events manager and or the lifecycle before method on the $app.

Here is my before.

$app->before(function () use ($app) {
  if ($app->session->get('isAuth') == false) {
    $app->response->setStatusCode(401,"Unauthorized");
    $app->response->setJsonContent('Unauthorized');
    return false;
  }
  return true;
});

The problem with this is it simply returns a 200 status page with no data. It just kills the app before executing the route and theirfor and theirfor $app->response is never served. It technically works but it would make debuggin ont eh back end really annoying for someone that dint' know that "Auth" was failing.

I could do something like this. Which technically works but i hate breaking out of the return $response; method

$app->before(function () use ($app) {
  if ($app->session->get('isAuth') == false) {
    header('HTTP/1.0 401 Unauthorized');
    header('Content-Type: application/json');
    echo json_encode('Unauthorized');
    return false;
  }
  return true;
});
edited Jun '16

The problem with this is it simply returns a 200 status page with no data. This means some exception or something like this IMHO check your logs.



79.0k
Accepted
answer
edited Jun '16

In your index.php, you need to either echo Micro APP handle() or to return response on your own.

For instance, in my micro app (API) on index.php I have this:

    // Handle the request
    $app->handle();

Then, in your business logic, before Micro method etc. you need to:

        $app->response->setStatusCode($status);
        $app->response->setContentType('application/json');
        $app->response->setJsonContent([Constantia::API_RETURN_ROOT_KEY => ['Status' => $status, 'Type' => 'ACCESS_DENIED', 'Error' => $msg, 'Code' => $code]]);
        $app->response->setHeader('Content-Length', strlen($app->response->getContent())); //Calculate Content-Length header
        $app->response->send();
        return false;

Normally, remove my constants, variables etc.

So the key here is to send response object if you don't echo your app handle():

$app->response->send();

I like to avoid echo as much as possible, and to use Response object to handle the response to the client.

Well good to know this. Well micro don't have dispatcher so i guess you are right.

edited Jun '16

This was it. Although you don't need to echo the $app->handle(); just handling it will work fine.

it was the $app->response->send(); that it was missing. that call must be called later in the the lifecycle by default but the return default stops the lifecycle event from firing. This was my overall question. And yes. Echoing out content is so direty that is why i asked for a better solution. i have always hated it. it feels like a hack for sure.

Heres the updated and working code

$app->before(function () use ($app) {   
    if (/* Auth Logic */){
        $app->response->setJsonContent('Unauthorized');
        $app->response->setStatusCode(401,"Unauthorized");
        $app->response->send();
        return false;
    }
    return true;
});

In your index.php, you need to either echo Micro APP handle() or to return response on your own.

For instance, in my micro app (API) on index.php I have this:

   // Handle the request
   $app->handle();

Then, in your business logic, before Micro method etc. you need to:

       $app->response->setStatusCode($status);
       $app->response->setContentType('application/json');
       $app->response->setJsonContent([Constantia::API_RETURN_ROOT_KEY => ['Status' => $status, 'Type' => 'ACCESS_DENIED', 'Error' => $msg, 'Code' => $code]]);
       $app->response->setHeader('Content-Length', strlen($app->response->getContent())); //Calculate Content-Length header
       $app->response->send();
       return false;

Normally, remove my constants, variables etc.

So the key here is to send response object if you don't echo your app handle():

$app->response->send();

I like to avoid echo as much as possible, and to use Response object to handle the response to the client.

Well, that's why I said either. Normally, returning entire response object will also work, but not in cases when you stop execution flow, that's why you need to flush output buffer withsend().

Well in full application you can do it, beacause return false just stop execution of dispatcher.

Well, that's why I said either. Normally, returning entire response object will also work, but not in cases when you stop execution flow, that's why you need to flush output buffer withsend().