Slim 3 中间件重定向
Slim 3 Middleware Redirect
我想检查用户是否登录。因此我有一个 Class returns true 或 false。现在我想要一个中间件来检查用户是否登录。
$app->get('/login', '\Controller\AccountController:loginGet')->add(Auth::class)->setName('login');
$app->post('/login', '\Controller\AccountController:loginPost')->add(Auth::class);
授权 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
}
}
}
因此当用户登录时页面将正确呈现。但是当用户没有自动访问时,我想重定向到主页。但是怎么办?!
$response->withRedirect($router->pathFor('home');
这行不通!
您需要return
回复。不要忘记 request
和 response
objects 是不可变的。
return $response = $response->withRedirect(...);
我有一个类似的 auth 中间件,我就是这样做的,它还添加了 403(未授权)header。
$uri = $request->getUri()->withPath($this->router->pathFor('home'));
return $response = $response->withRedirect($uri, 403);
使用:
http_response_code(303);
header('Location: ' . $url);
exit;
根据 tflight 的回答,您需要执行以下操作以使一切按预期工作。我试图将其作为修订提交,因为 tflight 的答案中提供的代码无法在开箱即用的框架上运行,但它被拒绝了,因此在单独的答案中提供它:
您的中间件需要添加以下内容:
protected $router;
public function __construct($router)
{
$this->router = $router;
}
此外,在声明中间件时,您需要添加以下构造函数:
$app->getContainer()->get('router')
类似于:
$app->add(new YourMiddleware($app->getContainer()->get('router')));
如果没有这些更改,解决方案将不起作用,您将收到 $this->router 不存在的错误。
完成这些更改后,您就可以使用 tflight
提供的代码
$uri = $request->getUri()->withPath($this->router->pathFor('home'));
return $response = $response->withRedirect($uri, 403);
制作基本 Middleware
并将 $container
注入其中,以便您所有的中间件都可以扩展它。
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
}
}
确保您的 Auth
中间件与基本中间件位于同一文件夹中,或者您可以使用命名空间。
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);
}
}
我想检查用户是否登录。因此我有一个 Class returns true 或 false。现在我想要一个中间件来检查用户是否登录。
$app->get('/login', '\Controller\AccountController:loginGet')->add(Auth::class)->setName('login');
$app->post('/login', '\Controller\AccountController:loginPost')->add(Auth::class);
授权 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
}
}
}
因此当用户登录时页面将正确呈现。但是当用户没有自动访问时,我想重定向到主页。但是怎么办?!
$response->withRedirect($router->pathFor('home');
这行不通!
您需要return
回复。不要忘记 request
和 response
objects 是不可变的。
return $response = $response->withRedirect(...);
我有一个类似的 auth 中间件,我就是这样做的,它还添加了 403(未授权)header。
$uri = $request->getUri()->withPath($this->router->pathFor('home'));
return $response = $response->withRedirect($uri, 403);
使用:
http_response_code(303);
header('Location: ' . $url);
exit;
根据 tflight 的回答,您需要执行以下操作以使一切按预期工作。我试图将其作为修订提交,因为 tflight 的答案中提供的代码无法在开箱即用的框架上运行,但它被拒绝了,因此在单独的答案中提供它:
您的中间件需要添加以下内容:
protected $router;
public function __construct($router)
{
$this->router = $router;
}
此外,在声明中间件时,您需要添加以下构造函数:
$app->getContainer()->get('router')
类似于:
$app->add(new YourMiddleware($app->getContainer()->get('router')));
如果没有这些更改,解决方案将不起作用,您将收到 $this->router 不存在的错误。
完成这些更改后,您就可以使用 tflight
提供的代码$uri = $request->getUri()->withPath($this->router->pathFor('home'));
return $response = $response->withRedirect($uri, 403);
制作基本 Middleware
并将 $container
注入其中,以便您所有的中间件都可以扩展它。
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
}
}
确保您的 Auth
中间件与基本中间件位于同一文件夹中,或者您可以使用命名空间。
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);
}
}