I am developing a mobile optimised website using Laravel 10. I have taken the user login and authentication code out of the box. It works on desktop and mobile except with one big exception. It seems the Chrome Password Manager on my Pixel 6 pre-fills and submits the CSRF token form before the Laravel application has had a chance to generate and set the CSRF token. This results in a token mismatch, triggering the 419 Page Expired error.

The user experience is like this... When Chrome's auto-fills the username and password it immediately sets it's token and triggers the 419 error. I don't even have a chance to select the 'Login' button. I can turn off the Chrome Password Manager which solves the issue but I can't ask my users to do that. I assume I need to intercept or suppress Chrome's token and let Laravel create it's own CSRF token.

I have checked online posts and this has been spotted for a while but I still haven't found a workaround that works. I am surprised there aren't more posts as this must be a major issue for developers. I can't imagine it is limited to just the Laravel framework. Your help would be appreciated.

I've tried to refresh the token. This is the middleware code. The web.php and Kernel.php files have been updated accordingly.

    use Closure;
    use Illuminate\Support\Facades\Auth;
    use Illuminate\Support\Str;

    class RefreshCsrfToken
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            if ($request->isMethod('post')) {
                // Regenerate the CSRF token
                $this->regenerateCsrfToken($request);
            }

            return $next($request);
        }

        /**
         * Regenerate the CSRF token.
         *
         * @param  \Illuminate\Http\Request  $request
         */
        protected function regenerateCsrfToken($request)
        {
            $session = $request->session();

            if ($session) {
                $session->regenerateToken(); // Regenerate the CSRF token
            }
        }
    }

This didn't work. Are there other approaches I should consider?

0

There are 0 best solutions below