【问题标题】:Slim 3 Middleware RedirectSlim 3 中间件重定向
【发布时间】:2016-07-30 23:51:36
【问题描述】:

我想检查用户是否登录。因此我有一个类女巫返回真或假。现在我想要一个检查用户是否登录的中间件。

$app->get('/login', '\Controller\AccountController:loginGet')->add(Auth::class)->setName('login');
$app->post('/login', '\Controller\AccountController:loginPost')->add(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
        }

    }
}

因此,当用户登录时,页面将正确呈现。但是当用户没有被自动化时,我想重定向到主页。但是怎么做?!

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

这行不通!

【问题讨论】:

    标签: php authentication slim slim-3


    【解决方案1】:

    您需要return 回复。不要忘记requestresponse 对象是不可变的。

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

    我有一个类似的身份验证中间件,我就是这样做的,它还添加了一个 403(未经授权)标头。

    $uri = $request->getUri()->withPath($this->router->pathFor('home'));
    return $response = $response->withRedirect($uri, 403);
    

    【讨论】:

    • 在 OP 的案例中,他们在使用之前没有定义 $router 变量。假设您的中间件没有从另一个类继承,您在哪里定义 $this->router
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      制作基本的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);
        }
      }
      

      【讨论】:

        【解决方案4】:

        用途:

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

        【讨论】:

        • 请尝试解释您的答案,而不仅仅是发布代码。
        • @NahuelIanni,如果你了解 PHP,那就不言自明了。
        • 虽然我确信这可能有效,但 OP 可能正在寻找使用 Slim 框架功能而不是普通 PHP 的解决方案。
        • @KimberlyW 我在中间件中找不到任何内置的东西。
        • 是的,这是一个解决方案,但不是一个合适的解决方案。
        猜你喜欢
        • 1970-01-01
        • 2018-06-18
        • 1970-01-01
        • 2020-02-13
        • 2016-11-07
        • 1970-01-01
        • 2022-08-03
        • 1970-01-01
        • 2018-12-01
        相关资源
        最近更新 更多