klein/klein.php

Running a response callback on every request and skipping all remaining routes. Is there a recommended way to do this?

Opened this issue · 0 comments

Here's what I wanted to do:

The very first respond callback defined:

On every request, look for a $_SESSION value.

If it is not found:
   render the login form view
   and skip checking all remaining routes and callbacks.

But $klein->skipRemaining() would always send a 404 not found header.

I want actual 404's to see a real 404 page but for accessing admin urls when not logged in I just want a redirect to the login page.

Here's what I did instead. It works. But I have a feeling there's a better way I'm supposed to be doing it.

$klein = new \Klein\Klein();

// Set default layout file:
$klein->service()->layout('app/layouts/1-column.php');

$klein->with('/admin', function () use ($klein) {

	// This first one is executed for every request.
	$klein->respond(function ($request, $response, $service) use ($klein) {
	
		// @todo check for the actual security related entries in session.
		if( empty($_SESSION) && empty($_POST) )
		{
			// Specify the login form view for rendering.
			$service->render('app/views/login.php');
			// Send 403 Forbidden http header and stop processing other routes.
			$klein->abort(403);
		}		
	});
	
	// ... more routes down here ...
	
});

//-----------------------------
// 404 not found handling
// Using exact code behaviors via switch/case
$klein->onHttpError(function ($code, $router) {
    switch ($code) {
        case 403:
             // access forbidden - redirected to login form
             break;
        case 404:
            $router->response()->body(
                '404 Not found, Y U so lost?!'
            );
            break;
        case 405:
            $router->response()->body(
                'You can\'t do that!'
            );
            break;
        default:
            $router->response()->body(
                'Oh no, a bad error happened that caused a '. $code
            );
    }
});
//-----------------------------

$klein->dispatch();

P.S.

You could initialize some sort of authorization in your constructor and then check if the user is allowed access at the beginning of each controller method that you want to lock down, etc. - #174 (comment)

The controllers I will be adding already do this but only for the few sections where we have user level and user group level permissions. For the majority of other sections we simply check if they are properly logged in or not so I thought that would be a good thing to put in an all-requests Klein callback.