问题
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