framework: [5.3] No access to sessions or auth on custom http error pages

  • Laravel Version: 5.3.28
  • PHP Version: 7.0.8-3ubuntu3 (cli)
  • Database Driver & Version: not relevant

Description:

When creating custom Blade views for displaying them to the users when a HTTP error occurs, I cannot access authentication or session variables inside. I’m aware that this happens because the standard “web” middleware does not apply to custom error pages, but I’m not sure if this is intentional. In comparison, the middleware that is applied on every request is also applied on custom pages.

If the behavior is intentional: Is there any way to apply middleware to the error pages, but not calling it on every request?

Steps To Reproduce:

  1. Create a custom error page, e.g. 404.blade.php and save it under views/errors/
  2. Try to access the Auth facade in side (e.g. just output another text on Auth::check();)
  3. Open up the page by accessing a not-defined URL

Related:

http://stackoverflow.com/questions/41517012/laravel-5-3-use-auth-middleware-on-custom-error-page

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 7
  • Comments: 31 (9 by maintainers)

Most upvoted comments

@manniL correct, There’s also another option. This is how I fixed it without jQuery:

I created a custom StartSession Class in App\Http\Middleware

<?php

namespace App\Http\Middleware;

use \Illuminate\Session\Middleware\StartSession as BaseStartSession;
use \Illuminate\Http\Request;
use Closure;

class StartSession extends BaseStartSession
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if($request->url() == "api/*"){
            return $next($request);
        }

        return parent::handle($request, $next);
    }
}

Notice the way it ignores API Routes.

Then I added that to the global middleware in kernal.php and removed the old startsession from web

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

Next I created a class called SessionServiceProvider.php in App\Providers

<?php

namespace App\Providers;

use Illuminate\Session\SessionServiceProvider as BaseSessionServiceProvider;
use App\Http\Middleware\StartSession;
class SessionServiceProvider extends BaseSessionServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->registerSessionManager();

        $this->registerSessionDriver();

        $this->app->singleton(StartSession::class);
    }
}

Then finally in app.php replace Illuminate\Session\SessionServiceProvider::class with App\Providers\SessionServiceProvider::class

I recommend doing composer dump-autoload and php artisan optimize in case it doesn’t work

I’ve already thought about setting the StartSession middleware as a global one, but there should be a better solution.

That’s the perfect solution if you want sessions across your whole application. Wouldn’t make sense to not do that actually. 😃


Something I do on one of my apps is actually send an ajax request from the error pages in order to query the session. That’s how the login button on StyleCI is able to show up on error pages.

image

image

Could you give us an example please?

I already posted the example. I’m not going to write your whole app for you I’m afraid. My description leaves it easy to implement yourself.

I’ve already thought about setting the StartSession middleware as a global one, but there should be a better solution.

That’s the perfect solution if you want sessions across your whole application. Wouldn’t make sense to not do that actually. 😃

Something I do on one of my apps is actually send an ajax request from the error pages in order to query the session. That’s how the login button on StyleCI is able to show up on error pages.

image

image

Sending AJAX request on 404 to trigger the session? This is nuts!

For those looking for an alternative, non-AJAX solution to this; What I did is create a new middleware group for web-rendered errors in the kernel which are then loaded in dynamically upon error rendering. Implementation details of this can be seen in this commit (Only Handler.php and Kernel.php changes are relevant).

Global middlewares are executed on a 404, but route-based middlewares aren’t. That’s because a 404 does not match a route, so there’s no knowledge about which middlewares should execute. You would probably need to modify your exception handler to call the relevant middlewares (at least EncryptCookies and StartSession) when needed.

This is the intended behaviour. You can’t expect laravel to guess whether a root mismatch wants sessions, because then 404s on your api would also start sessions.

@sisve Thanks for the reply! Yes, I forgot to mention that global middleware is executed indeed. I’ve linked my question on StackOverflow which relates to the same topic. I’ve already thought about setting the StartSession middleware as a global one, but there should be a better solution.

Do you have an approach for modifying the exception handler for this particular case?