2

Я создал класс промежуточного программного обеспечения с именем PathParser, который запускается по каждому запросу. Цель состоит в том, чтобы обрабатывать запросы для «URL-адресов тщеславия», которые мы разрешили пользователям создавать в нашем пред-Laravel php-приложении. Например: Пользователь создал путь URL, например: http://example.com/i-love-this-place

Что такое PathParser, это проверить на 404 ответа, а затем посмотреть, соответствует ли путь URL одному из наших старых путей тщеславия. Как это:

class PathParser 
{ 
    public function handle($request, Closure $next, $guard = null) 
    { 
     $next_response = $next($request);  
     $status_code = $next_response->getStatusCode(); 

     if ($status_code === 404) { 
      $script_url = $request->server("SCRIPT_URL"); 

      $vanity_controller = new VanityController(); 
      $found_vanity_id = Search::findVanityPath($script_url); 

      if (!empty($found_vanity_id)) { 
       $next_response = response()->make($vanity_controller->one($found_vanity_id)); 
      } 
     } 

     return $next_response; 
    } 
} 

Предположим следующее:

  1. Пользователь никогда не создал URL путь, который будет конфликтовать с любым маршрутом

  2. Я должен поддержать ряд существующих (pre-Laravel) URL-адреса тщеславия, которые находятся в дикой природе - отправляются в социальные сети и т. д.

В Kernel.php я следующее:

protected $middleware = [ 
     \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, 
     \App\Http\Middleware\PathParser::class, 
     //\Illuminate\Session\Middleware\StartSession::class, 
     //\Illuminate\View\Middleware\ShareErrorsFromSession::class, 
    ]; 

    protected $middlewareGroups = [ 
     'web' => [ 
      \App\Http\Middleware\EncryptCookies::class, 
      \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 
      \Illuminate\Session\Middleware\StartSession::class, 
      \Illuminate\View\Middleware\ShareErrorsFromSession::class, 
      \App\Http\Middleware\VerifyCsrfToken::class, 
      \Illuminate\Routing\Middleware\SubstituteBindings::class, 
     ],  
    ]; 

В $ промежуточного массива я попытался добавил StartSession и ShareErrorsFromSession (раскомментировав 2 строки выше), и это работает частично. Но с двумя основных проблемами:

  • Auth :: пользователь имеет нулевое значение, даже для запросов к тщеславию путям по зарегистрированным пользователям
  • $ ошибок больше не получают заполняются по форме представления (например, на страницы регистрации и входа в систему), когда пользователь отправляет неверную/недействительную информацию

Есть ли способ проверить маршрут по всем запросам и получить аутентифицированный пользователь, также сохраняя ошибки $?

У меня такое чувство, что я недостаточно понимаю жизненный цикл запроса, чтобы добиться успеха. Но может быть, есть способ?

Если это не возможно, чтобы делать то, что мне требуется, а затем использовать 302 перенаправления на стандартизированную приставке пути (например, как http://example.com/тщеславия/я-любовь-это место) является прекрасным решением. Но я надеюсь, что есть еще один способ.

+1

Есть причина, вы не можете добавьте свой 'PathParser' в конец вашей промежуточной группы' web'? – patricus

+0

Когда я помещал PathParser в массив промежуточного программного обеспечения в Интернете, любой запрос «пути суеты» идет прямо на встроенную страницу 404 Laravel и полностью обходит PathParser. На самом деле, структура даже не создает экземпляр PathParser - я могу поместить в нее плохой синтаксис и сохранить его, и нет никакого исключения, просто до 404. Но когда я нахожу подходящий маршрут, появляется это синтаксическое исключение. И, возможно, это дает нам подсказку - я имею в виду, возможно, есть способ обойти автоматическую обработку 404 Laravel (что может привести к решению)? – udog

+0

Ах, да, это имеет смысл. Согласование маршрута выполняется до того, как применяется промежуточное ПО маршрута, поэтому исключение «NotFoundHttpException» будет выбрано до того, как ваше промежуточное программное обеспечение будет выполнено. – patricus

ответ

1

Пар предложения:

Если вам не нужны Auth/сессии/и т.д., то вы можете просто обрабатывать Symfony\Component\HttpKernel\Exception\NotFoundHttpException исключения внутри обработчика исключений приложения.

В app/Exceptions/Handler.php, изменить метод render() выглядеть примерно так:

public function render($request, Exception $e) 
{ 
    if ($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) { 
     // your code that returns a Response 
    } 

    return parent::render($request, Exception $e); 
} 

Если вам не нужно AUTH/сессия/и т.д., я хотел бы предложить создание «прием всего» маршрута в конце файла маршрутов.Например, в качестве последней строки в файле routes/web.php, говоря:

Route::any('{catchall}', '[email protected]')->where('catchall', '(.*)'); 

Затем внутри вашего VanityController, есть handle метод, который выглядит следующим образом:

public function handle(Request $request, $url) 
{ 
    // logic to search and render your vanity page for $url 

    // if no vanity page was found: 
    throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException(); 
} 
+0

Это решение является тщательным и отлично работает, как только я его реализовал - я использовал весь маршрут, но также приятно знать, что я мог бы обрабатывать исключения HTTP выборочно. – udog