9

I want to check if a user is logged in. Therefor I have an Class witch returns true or false. Now I want a middleware which checks if the user is logged in.

$app->get('/login', '\Controller\AccountController:loginGet')->add(Auth::class)->setName('login');
$app->post('/login', '\Controller\AccountController:loginPost')->add(Auth::class);

Auth Class

class Auth {
    protected $ci;
    private $account;

    //Constructor
    public function __construct(ContainerInterface $ci) {
        $this->ci = $ci;
        $this->account = new \Account($this->ci);
    }

    public function __invoke($request, \Slim\Http\Response $response, $next) {
        if($this->account->login_check()) {
            $response = $next($request, $response);
            return $response;
        } else {
            //Redirect to Homepage
        }

    }
}

So when the user is logged in the page will render correctly. But when the user is not autoriesed I want to redirect to the homepage. But how?!

$response->withRedirect($router->pathFor('home');

This doesn't work!

Stefan Roock
  • 153
  • 1
  • 5

4 Answers4

10

You need to return the response. Don't forget that the request and response objects are immutable.

return $response = $response->withRedirect(...);

I have a similar auth middleware and this is how I do it which also adds a 403 (unauthorized) header.

$uri = $request->getUri()->withPath($this->router->pathFor('home'));
return $response = $response->withRedirect($uri, 403);
tflight
  • 124
  • 1
  • 5
  • In OP's case, they didn't define a `$router` variable before using it. Where do you define `$this->router` assuming your Middleware didn't inherit from another class? – The Unknown Dev Dec 12 '16 at 20:27
3

Building off of tflight's answer, you will need to do the following to make everything work as intended. I tried to submit this as a revision, given that the code provided in tflight's answer would not work on the framework out of the box, but it was declined, so providing it in a separate answer:

You will need the following addition to your middleware:

protected $router;

public function __construct($router)
{
    $this->router = $router;
}

Additionally, when declaring the middleware, you would need to add the following the constructor:

$app->getContainer()->get('router')

Something similar to:

$app->add(new YourMiddleware($app->getContainer()->get('router')));

Without these changes, the solution will not work and you will get an error that $this->router does not exist.

With those changes in place you can then utilize the code provided by tflight

$uri = $request->getUri()->withPath($this->router->pathFor('home'));
return $response = $response->withRedirect($uri, 403);
conrad10781
  • 2,223
  • 19
  • 17
0

make basic Middleware and inject $container into it so all your middleware can extends it.

Class Middleware
{
  protected $container;

  public function __construct($container)
  {
    $this->container = $container;
  }

  public function __get($property)
  {
    if (isset($this->container->{$property})) {
      return $this->container->{$property};
    }
    // error
  }
}

make sure your Auth middleware on the same folder with basic middleware or you can use namespacing.

class Auth extends Middleware
{
  public function __invoke($request, $response, $next)
  {
    if (!$this->account->login_check()) {
      return $response->withRedirect($this->router->pathFor('home'));
    }

    return $next($request, $response);
  }
}
ghabriel
  • 123
  • 9
-1

Use:

http_response_code(303);
header('Location: ' . $url);
exit;
Geoffrey
  • 5,407
  • 10
  • 43
  • 78