skip to Main Content

I am struggling with that for a while now.
When I logout and straight Login again, I get a 419 Error through the API.
I need to refresh the login page to get a new CSRF token.
I anticipate that I originally planned to use Inertia and SSR but am using only Inertia in the end (NO SSR)

I checked my full logout procedure and the session gets correctly destroyed (I asume):

Route::get(LaravelFortifyRoutePath::for('signout', '/signout'), 
[LaravelFortifyHttpControllersAuthenticatedSessionController::class, 'destroy'])->name('signout');

the original AuthenticatedSessionController does

     $this->guard->logout();

    if ($request->hasSession()) {
        $request->session()->invalidate();
        $request->session()->regenerateToken();
    }
    Log::debug('session invalidated'); <<< included for testing reasons

    return app(LogoutResponse::class);

and i get the session invalidate message
My Login is:

Route::get('login', function () {
    return Inertia::render('auth/cover-login');
})->name('login');

So at the moment my only explanation left is that the Inertia render returns somehow a cached version which only gets overwritten by a page refresh.

Any clue or help on how to solve that?

EDIT: I rechecked the Inertia doc, found this:

Laravel automatically includes the proper CSRF token when making
requests via Inertia or Axios. However, if you’re using Laravel, be
sure to omit the csrf-token meta tag from your project, as this will
prevent the CSRF token from refreshing properly.

So I removed the token as a meta tag, but still need this one:

<script>window.Laravel = {csrfToken: '{{ csrf_token() }}'}</script>

for the app to work, no change, same error…

2

Answers


  1. Chosen as BEST ANSWER

    I have found a dirty hack concerning this issue.

    The strange thing is this error appears only on post requests but not with get. I even get 419 errors once logged in, until I make the first reload. The root of the problem is yet unknown to me, I believe it has to do with Inertia rendering, but could not pinpoint at.

    The solution though is quite simple, but dirty: During the setup of the components , in that case the login.vue, I include a check419 const

    const check419 = async() => {
        var params = {
            check:true,
        };
    
        await axios.post(route('check419'),params)
            .catch((error) => {
                console.log(error);
                if (error?.response?.status === 419) {
                    window.location.reload();
                }
            })
    }
    
    check419();
    

    api.php

    Route::post('check419', 'AppHttpControllersAuthController@check419')->name('check419');

    AuthController (does nothing in fact):

        public function check419(Request $request)
        {
        Log::debug("=======> entering check419 =======>");
        try {
            $validated = $request->validate([
            ]);
    
        } catch (Exception $e) {
            Log::error($e,[$request]);
            throw $e;
        }
        Log::debug("<======= exit check419 <=======");
    }
    

    Like this, if during setup the post fails with a 419, the page reload gets autoatically triggered, the token refreshed and user barely notices the reload and later finds no 419 error.

    Also components within the app which get a 419 during their post requests get a simple page reload when encountering a 419.

    Problem solved, diry though but it works and user barely notices it.

    Now if anyone has a better solution, I'm open to it


  2. I found a solution to this, however I am very inexperienced with Vue so I don’t know why it is working exactly. Here is how I updated the logout function on AppLayout.vue:

        const logout = () => {
            Inertia.post(route('logout'), {}, {
                onFinish: () => {
                    console.log('Logged out successfully!');
                },
                onError: (errors) => {
                    console.error('Error during logout:', errors);
                },
            });
        };

    I had to add run npm install @inertiajs/inertia and import it on the layout page:

    import { Inertia } from '@inertiajs/inertia';

    Let me know if I am off base, but I believe this works because the logout forces a new request which updates the csrf token instead of just destroying the session token. I believe there is some re-routing that is supposed to happen in laravel if the csrf token is invalid. But maybe it isn’t being triggered? This fixes the login since it allows for a proper logout and grabs the updated sanctum csrf token. I’m curious if anyone has any insight on the mechanics behind this.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search