Laravel 5:404 路线上的会话
Posted
技术标签:
【中文标题】Laravel 5:404 路线上的会话【英文标题】:Laravel 5: Sessions on 404 route 【发布时间】:2016-09-05 15:31:05 【问题描述】:这让我疯狂了好几个星期: 如何在 404 页面上提供会话?我只是 在我的默认模板中嵌入 404 错误页面。它还显示导航栏 和页脚,但如何让我的用户在 404 上保持登录状态?
在 404 Auth::check() 上总是返回 false,并且会话特定的所有其他内容都是 null 或空。
如何在 (404) 错误页面上启用会话?
【问题讨论】:
您找到答案了吗?我也有同样的问题。 @RobinvanBaalen 不幸的是:( 【参考方案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);
这达到了两个要求:
-
所有
web
中间件都为请求正确运行
有效的 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 验证错误不会显示在视图页面上。以上是关于Laravel 5:404 路线上的会话的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 API 令牌在 laravel 中进行用户模拟?
如果在 Laravel 5.1 中找不到路由,则显示 404 页面
Laravel 5.4 上的示例 PHPUnit 测试失败并显示 404