Laravel 5 迁移到Laravel、虚荣URL、所有请求的中间件、Auth::user和$errors问题

Laravel 5 迁移到Laravel、虚荣URL、所有请求的中间件、Auth::user和$errors问题,laravel-5,laravel-5.3,laravel-routing,laravel-middleware,laravel-request,Laravel 5,Laravel 5.3,Laravel Routing,Laravel Middleware,Laravel Request,我创建了一个名为PathParser的中间件类,它在每个请求上运行。其目的是处理“虚荣URL路径”的请求,我们允许用户在我们的pre-Laravel vanilla PHP应用程序中创建这些路径。例如:用户创建了URL路径,例如: PathParser所做的是检查404响应,然后查看URL路径是否匹配我们的一个旧路径。像这样: class PathParser { public function handle($request, Closure $next, $guard = nu

我创建了一个名为PathParser的中间件类,它在每个请求上运行。其目的是处理“虚荣URL路径”的请求,我们允许用户在我们的pre-Laravel vanilla PHP应用程序中创建这些路径。例如:用户创建了URL路径,例如:

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;
    }
}
假设如下:

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,
        ],    
    ];
  • 用户从未创建过与任何路由冲突的URL路径

  • 必须支持大量现有的(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,
            ],    
        ];
    
    在$middleware数组中,我尝试添加StartSession和ShareErrorsFromSession(取消上面两行的注释),这部分起作用存在两个主要问题:

    • Auth::user为null,即使对于登录用户对虚拟路径的请求也是如此
    • 当用户提交错误/无效信息时,$errors不再在表单提交时填充(例如在注册和登录页面上)
    有没有一种方法既可以检查所有请求的路由,又可以找到经过身份验证的用户,同时还可以保留$errors

    我有一种感觉,我对请求生命周期的理解不足以成功。但也许有办法

    如果无法满足我的要求,那么使用302重定向到标准化的前缀路径(例如虚荣/I-love-this-place)是一个很好的解决方案。但我希望还有另外一种方法。

    一些建议:

    如果不需要auth/sessions/etc,则可以在应用程序的异常处理程序中处理
    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/sessions/etc,我建议在routes文件的末尾创建一个“catchall”路由。例如,作为
    routes/web.php
    文件的最后一行,将:

    Route::any('{catchall}', 'VanityController@handle')->where('catchall', '(.*)');
    
    然后,在您的
    VanityController
    中,有一个
    句柄
    方法,该方法如下所示:

    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();
    }
    

    有什么原因不能将
    PathParser
    添加到
    web
    中间件组的末尾吗?当我将PathParser放入web中间件阵列时,任何对“虚荣路径”的请求都会直接进入Laravel的内置404页面,并完全绕过PathParser。事实上,这个框架甚至没有实例化PathParser——我可以在其中放入错误的语法并保存它,没有例外,直接到404。但当我找到一条正确的路线时,就会出现语法异常。也许这给了我们一个提示——我的意思是,也许有一种方法可以绕过Laravel的自动404处理(这可能导致一个解决方案)?啊,是的,这是有道理的。路由匹配是在应用路由中间件之前执行的,因此在中间件执行之前会抛出
    NotFoundHttpException
    异常。这个解决方案是彻底的,并且在我实现它之后就可以完美地工作——我使用了catchall路由,但知道我可以有选择地处理HTTP异常也很好。