Erdem Ece
Erdem Ece

Reputation: 1775

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.

Upvotes: 1

Views: 1989

Answers (2)

the-noob
the-noob

Reputation: 1342

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;
}

Upvotes: 1

CrazyCrow
CrazyCrow

Reputation: 4235

Well the basic example is next

<?php

require 'vendor/autoload.php';

session_start();

class Auth {
    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;
    }
}

$app = new \Slim\App();

$app->get('/open', function($request, $response, $args){
    echo 'HAPPINESS FOR EVERYBODY, FREE, AND LET NO ONE BE LEFT BEHIND!';
});

$app->get('/closed', function($request, $response, $args){
    echo 'You are authenticated!';
})->add(new Auth());

$app->get('/login', function($request, $response, $args){
    $_SESSION['userid'] = 1;
});

$app->run();

I think there was a mistake in as authenticate function as !isset means there is no $_SESSION['userid'] and probably user is not logged in and your function tells that he is logged.

But anyway you can add middleware to single route or group of routes with add() method.

Upvotes: 1

Related Questions