【问题标题】:Laravel 5: Sessions on 404 routeLaravel 5:404 路线上的会话
【发布时间】:2016-09-05 15:31:05
【问题描述】:

这让我疯狂了好几个星期: 如何在 404 页面上提供会话?我只是 在我的默认模板中嵌入 404 错误页面。它还显示导航栏 和页脚,但如何让我的用户在 404 上保持登录状态?

在 404 Auth::check() 上总是返回 false,并且会话特定的所有其他内容都是 null 或空。

如何在 (404) 错误页面上启用会话?

【问题讨论】:

  • 您找到答案了吗?我也有同样的问题。
  • @RobinvanBaalen 不幸的是:(

标签: php laravel session http-status-code-404


【解决方案1】:

对于 Laravel 5.5.5 或更高版本,只需使用 Route::fallback:

Route::fallback('PagesController@notFound');

这将帮助您自定义 404 视图以访问所有会话等内容。

【讨论】:

    【解决方案2】:

    我真的不明白这些答案中的任何一个有多棒。它们过于复杂,并倾向于建议使用额外的路由重建内核,从而导致内存和 cpu 使用量激增,只是为了创建一个 404 页面。

    我建议只创建您需要的路线,而不是使用 Laravel 页面建议的自动错误页面。在较新版本的 Laravel 中,这一点得到了改进,但对于这个版本,我只推荐以下内容:

    routes.php

    Route::group(['middleware' => ['web']], function ($router) {
        $router->get('/404', [
            'uses' => 'HttpErrorController@404',
            'as' => 'errors.404',
        ]);
    });
    

    显然取决于您的设置方式,这就是我使用路由并创建HttpErrorController 来处理路由的方式,这就是它已经在web 中间件组中的原因

    App\Exceptions\Handler.php

    public function render($request, Exception $exception) 
    {
    
        if ($this->isHttpException($exception) && $exception->getStatusCode() === 404) 
        {
            return redirect()->route('404');
        }
    
        return parent::render($request, $exception);
    }
    

    你可以以任何你认为合适的方式处理这些,在其中添加一个开关,检查它是否是一个 json 请求,然后以不同的方式处理等等

    【讨论】:

      【解决方案3】:

      为避免出现其他异常或使用api中间件接收请求时出现问题,请将App/Exceptions/Handler.php中的渲染函数更改为:

       public function render ($request, Exception $exception)
      {
          if ($this->isHttpException($exception)) {
              switch ($exception->getStatusCode()) {
                  case '404':
                      \Route::any(request()->path(), function () use ($exception, $request) {
                          return parent::render($request, $exception);
                      })->middleware('web');
                      return app()->make(Kernel::class)->handle($request);
                      break;
                  default:
                      return $this->renderHttpException($exception);
                      break;
              }
          } else {
      
              return parent::render($request, $exception);
          }
      }
      

      【讨论】:

        【解决方案4】:

        所以我知道这是一个老问题,但如果有人觉得它有用,这就是我处理这个问题的方式:

        在我的App/Exceptions/Handler.php 中,我将默认的render 方法更改为:

        public function render($request, Exception $exception) {        
            \Route::any(request()->path(), function () use ($exception, $request) {
                return parent::render($request, $exception);
            })->middleware('web');
            return app()->make(Kernel::class)->handle($request);
        }
        

        这达到了两个要求:

        1. 所有web 中间件都为请求正确运行
        2. 有效的 API 路由不会启动会话

        这实际上是一个决定,将web 中间件组设置为在出现错误时运行的默认值。 Laravel 通常不会在错误页面上运行任何中间件组。如果需要或使用其他条件,例如,您当然可以指定其他中间件或其他路由参数。如果路径以api/ 开头,则使用api 中间件,而不是使其更加一致。

        希望这对某人有所帮助。

        【讨论】:

          【解决方案5】:

          只是对现有答案进行一些扩展:确保从 $middlewareGroups 中删除该中间件(如果它也存在的话),这样您就不会两次应用该中间件。

          你会得到这样的结果:

          protected $middleware = [
              \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
              \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
              \App\Http\Middleware\TrimStrings::class,
              \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
              \Illuminate\Session\Middleware\StartSession::class,
              \Illuminate\Session\Middleware\AuthenticateSession::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\Session\Middleware\AuthenticateSession::class,
                  //\Illuminate\View\Middleware\ShareErrorsFromSession::class,
                  \App\Http\Middleware\VerifyCsrfToken::class,
                  \Illuminate\Routing\Middleware\SubstituteBindings::class,
              ],
          
              'api' => [
                  'throttle:60,1',
                  'bindings',
              ],
          ];
          

          据我了解,这是因为处理会话的中间件,因为位于 web 组中,仅适用于在 web.php 上路由的那些页面。而且由于默认错误处理不会重定向到路由页面,因此我们无法访问会话。

          这样中间件将应用于所有页面,而不仅仅是那些在 web.php 上路由的页面,包括错误页面。

          我最初找到了here 的解决方案,但我花了一段时间才明白为什么会发生这种情况(我以为我完全搞错了,请随时确认或更正)。

          希望它有所帮助,它在 Laravel 5.4 上对我有用

          【讨论】:

          • 这个解决方案一直让我退出
          【解决方案6】:

          您可以做的是,在 app/http/Kernel.php 中添加以下代码块:

              \Illuminate\Session\Middleware\StartSession::class,
              \Illuminate\View\Middleware\ShareErrorsFromSession::class,
          

          在 $middleware 变量中。所以它看起来像:

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

          它对我有用,我希望它也对你有用。

          【讨论】:

          • 谢谢。你能解释一下为什么没有它就不能工作吗?这个改变有什么不同?
          • 此更改会将会话中间件添加到每个请求中。如果您像我们一样拥有无状态 API 层,那么这不是解决方案,因为会话也会添加到您的 API 请求中。
          • 谢谢..而且我认为您需要注销并登录。因为它没有在该页面上设置会话 ID。
          • 更改后 laravel 验证错误不会显示在视图页面上。
          猜你喜欢
          • 1970-01-01
          • 2015-07-31
          • 2016-08-05
          • 2018-11-22
          • 2018-12-07
          • 2018-10-04
          • 2018-10-23
          • 2020-05-13
          • 2015-12-11
          相关资源
          最近更新 更多