Slim 3 Middleware Redirect

笑着哭i 提交于 2020-04-10 08:20:53

问题


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!


回答1:


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



回答2:


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



回答3:


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



回答4:


Use:

http_response_code(303);
header('Location: ' . $url);
exit;


来源:https://stackoverflow.com/questions/36521233/slim-3-middleware-redirect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!