2017-02-22 5 views
0

Целью является перенаправление пользователя на страницу входа из промежуточного программного обеспечения. Промежуточное вызывается из тонкой группы маршрутов с этой линией:Правильный способ перенаправления из slim middleware

$this->get('/profile', ProfileController::class . ':index')->add(new RequireLogin()); 

А вот Промежуточное программное обеспечение

<?php 

namespace Rib\Src\MiddleWares; 


use Rib\Src\Services\FlashMessages; 
use Slim\Http\Request; 
use Slim\Http\Response; 

class RequireLogin 
{ 


    /** 
    * Example middleware invokable class 
    * 
    * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request 
    * @param \Psr\Http\Message\ResponseInterface $response PSR7 response 
    * @param callable $next Next middleware 
    * 
    * @return \Psr\Http\Message\ResponseInterface 
    */ 
    public function __invoke($request, $response, $next) 
    { 

     if (! isset($_SESSION[ 'id' ])) { 
      FlashMessages::flashIt('message', "The page you tried to access requires an active session. Please log back in."); 
      header('Location: /user/login'); # THIS LINE 
      exit; # AND THIS ONE 
     } 



     $response = $next($request, $response); 

     return $response; 
    } 

} 

Моя цель состоит в том, что, когда промежуточного слоя определяет, что пользователь не вошли в систему, то перенаправить пользователя на страницу входа. Вы можете видеть, что мой текущий путь - ПЛОХО: я использую перенаправление, за которым следует выход.

Как я могу заменить эти 2 строки соответствующим «тонким» способом?

ответ

2

Response имеет удобный метод withRedirect(), вы можете использовать его как это:

<?php 

if (!isset($_SESSION[ 'id' ])) { 
    FlashMessages::flashIt('message', "The page you tried to access requires an active session. Please log back in."); 
    $url = '/user/login'; 
    return $response->withRedirect($url); 
} else { 
    return $next($request, $response); 
} 

Однако есть еще одна проблема: вы жестко прописывать URL, где вы хотите без аутентификации пользователей перенаправлены. Рассматривайте получить, что URL-адрес с помощью его имени (что вы можете дать при объявлении маршрута):

<?php 

// Add unique name to the route so you can 
// refer to it later in the code (this is what we're going to do now) 
$app->get('/user/login', YourController::class)->setName('userLoginPage'); 

Теперь вы можете обратиться к этому маршруту через имя, а не сам URL в ЕМ. Для этого необходимо внедрить объект Тонкий маршрутизатор:

<?php 

namespace Rib\Src\MiddleWares; 


use Rib\Src\Services\FlashMessages; 
use Slim\Http\Request; 
use Slim\Http\Response; 
use Slim\Router; 

class RequireLogin 
{ 
    /** 
    * Object constructor 
    * 
    * Inject Slim Router here, so you can access route names. 
    * 
    * @param Router $router 
    */ 
    public function __construct(Router $router) 
    { 
     $this->router = $router; 
    } 

    /** 
    * Example middleware invokable class 
    * 
    * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request 
    * @param \Psr\Http\Message\ResponseInterface $response PSR7 response 
    * @param callable $next Next middleware 
    * 
    * @return \Psr\Http\Message\ResponseInterface 
    */ 
    public function __invoke($request, $response, $next) 
    { 

     if (! isset($_SESSION[ 'id' ])) { 
      FlashMessages::flashIt('message', "The page you tried to access requires an active session. Please log back in."); 
      // Get url by name: this is more flexible than hardcoding URL 
      $url = $this->router->pathFor('userLoginPage') . ' #forbidden'; 
      return $response->withRedirect($url); 
     } else { 
      return $next($request, $response); 
     } 
    } 

} 

Преимущество здесь в том, что при изменении фактического URL для страницы входа пользователя, вам не придется менять его в ПО промежуточного слоя, так как он доступен через $router->pathFor() метод.

Я бы сказал, что это очень тонкий, приятный способ.)

+0

Очень приятно! На самом деле я никогда не рассматривал метод setName на маршруте. Не является поклонником жестких правил кодирования в промежуточном программном обеспечении или классах. – Rob

Смежные вопросы