Home Documentation GitHub Support

Middlewares

Introduction

A middleware is a mechanism designed to protect routes and filter incoming requests to your application. This means, before entering a controller and calling an action, the middleware will perform some tasks to ensure that this process is allowed, and then tell Glowie router to continue or not the execution.

Example: Authentication. You have an admin page that only logged in users are allowed to access. With a middleware you can protect this restricted areas to properly check if the user is logged in before entering them. If he is not, the user is redirected back to the login page.

Basically, a middleware is an "extra layer" added between the route and the controller.

Creating a middleware

A middleware is a simple PHP file with a middleware class in Glowie\Middlewares namespace stored in app/middlewares folder.

From Firefly CLI you can use the following command to create a new middleware:

php firefly create-middleware --name=MyMiddleware

The middleware file must have the exact same name as the middleware class.

This is the default snippet for a middleware file:

<?php
    namespace Glowie\Middlewares;

    use Glowie\Core\Http\Middleware;

    class MyMiddleware extends Middleware{

       /**
        * The middleware handler.
        * @return bool Should return true on success or false on fail.
        */
       public function handle(){
           // This method is required
       }

    }

?>

Assigning a route to a middleware

To create a protected route assigned to a middleware, in your route configuration file (see Routes), use the static Rails::addProtectedRoute() method.

This is basically the same as Rails::addRoute() method, with a difference that the second parameter is the full class name for the application middleware that will protect this route.

The middleware name must also include Glowie\Middlewares namespace. You can use MiddlewareName::class to get this property properly (see the example below).

If no middleware is specified, Glowie\Middlewares\Authenticate will be used by default.

Example

use Glowie\Controllers\Admin;
use Glowie\Middlewares\Authenticate;

# myappurl.com/admin
Rails::addProtectedRoute('admin', Authenticate::class, Admin::class, 'index');

Multiple middlewares If you want to assign multiple middlewares to a route, you can pass an array of middlewares as the second parameter of this method. Be aware that each middleware will be executed following the same order as in the array.

Example

use Glowie\Controllers\Login;
use Glowie\Middlewares\Authenticate;
use Glowie\Middlewares\ValidateCsrfToken;

# myappurl.com/login
Rails::addProtectedRoute('login', [ValidateCsrfToken::class, Authenticate::class], Login::class, 'index');

Middleware handler

Every middleware class must have a public handle() method. This is the method where the middleware validation logics will run when the protected route is called.

This method must return true or false, indicating if Glowie router should continue the execution or not.

Example

<?php
    namespace Glowie\Middlewares;

    use Glowie\Core\Http\Middleware;

    class MyMiddleware extends Middleware{

       /**
        * The middleware handler.
        * @return bool Should return true on success or false on fail.
        */
       public function handle(){
           // Checks if the "token" header token is valid
           if($this->request->getHeader('token') == '1a79a4d60de6718e8e5b326e338ae533'){
               return true; # Continues to the controller
           }else{
               return false; # Stops the execution
           }
       }

    }

?>

Middleware success

If the middleware handler method returns true, Glowie will send the request to the corresponding route controller and action. But, if you want the middleware to run something before that, you can create an optional public success() method in the middleware class.

Example

<?php
    namespace Glowie\Middlewares;

    use Glowie\Core\Http\Middleware;

    class MyMiddleware extends Middleware{

       /**
        * The middleware handler.
        * @return bool Should return true on success or false on fail.
        */
       public function handle(){
           // Checks if the "token" header token is valid
           if($this->request->getHeader('token') == '1a79a4d60de6718e8e5b326e338ae533'){
               return true; # Continues to the controller
           }else{
               return false; # Stops the execution
           }
       }

       /**
        * Called if the middleware handler returns true.
        */
       public function success(){
           // Header is valid, store it in the session
           $this->session->token = $this->request->getHeader('token');

           // After this, the route controller is triggered
       }

    }

?>

Middleware fail

If the middleware handler method returns false, Glowie will stop the route execution and return a 403 Forbidden response error. If you want to do something else if this happens, you can create an optional public fail() method in the middleware class and this method will be called instead.

Example

<?php
    namespace Glowie\Middlewares;

    use Glowie\Core\Http\Middleware;

    class MyMiddleware extends Middleware{

       /**
        * The middleware handler.
        * @return bool Should return true on success or false on fail.
        */
       public function handle(){
           // Checks if the "token" header token is valid
           if($this->request->getHeader('token') == '1a79a4d60de6718e8e5b326e338ae533'){
               return true; # Continues to the controller
           }else{
               return false; # Stops the execution
           }
       }

       /**
        * Called if the middleware handler returns false.
        */
       public function fail(){
           // Header is not valid, redirect the user back to the index page
           $this->response->redirect('/');
       }

    }

?>

The init() method

Every middleware can have an optional init() method. If this method exists, it will be called before the middleware handler.

This way you create common functions that will be propagated to the whole middleware before anything happens.

Note: You should not use the __construct() method in a middleware. Always use init() instead.

Example

<?php
    namespace Glowie\Middlewares;

    use Glowie\Core\Http\Middleware;

    class MyMiddleware extends Middleware{

       public function init(){
           // init methods goes here
       }

       /**
        * The middleware handler.
        * @return bool Should return true on success or false on fail.
        */
       public function handle(){
           // init() will be called before this method is triggered
           return true;
       }

    }

?>