Search code examples
phpoopslimmiddlewareslim-3

How to implement a Slim v2 hook as middleware in Slim v3


In Slim Framework v2 I use simple authentication function as a hook to check if a route needs login.

This is authentication code:

$authenticate = function ( $app ) {
    return function () use ( $app ) {
        if ( !isset( $_SESSION['userid'] ) ) {
            $_SESSION['urlRedirect'] = $app->request()->getPathInfo();
            $app->flash('danger', 'You need to login');
            $app->redirect('/login');
        }
    };
};

this is how I use in Slim v2:

$app->get("/user/change-password", $authenticate($app), function () use ( $app ) {

 $userStuff->changePassowrd($_SESSION['userid'], $newPassword, $oldPassword);

});

I can implement this to Slim v3 without a problem but I can't seem to understand how I supposed to do this with middleware(to learn and use the functionally)

I have tried this: this is my middleware class;

<?php
namespace entity;

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

class Auth
{
    /**
     * Example middleware invokable class
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $request  PSR7 request
     * @param  \Psr\Http\Message\ResponseInterface      $response PSR7 response
     * @param  callable                                 $next     Next middleware
     *
     * @return \Psr\Http\Message\ResponseInterface
     */
     public function __invoke($request, $response, $next)
     {
       if ($this->authenticate()) {
        $response = $next($request, $response);
      } else {
        echo 'You need to login';
      }
      return $response;
     }

     public function authenticate() {
       if ( !isset( $_SESSION['userid'] ) ) {
          return true;
       }
       return false;
     }
}

?>

Registered it:

$app->add( new entity\Auth() );

and I don't know how to use this on a route as I did in Slim v2, where do I add this in the route to check if that route needs an authentication?

Thanks.


Solution

  • What you are looking for is actually excluding a route for the Auth middleware. You do want that check for all other routes but not for changePassword.

    In your __invoke you need to get the current route and only do authenticate if the route is not changePassword (if that's the name of your route).

    public function __invoke($request, $response, $next)
    {
        $route = $request->getAttribute('route');
        if (in_array($route->getName(), ['changePassword']) || $this->authenticate()) {
            $response = $next($request, $response);
        } else {
            echo 'You need to login';
        }
        return $response;
    }