EricMashiyane's avatar

Error 419

Hi Guys , I am struggling with Error 419 here, I have tried multiple ways to see whats wrong including debugging cookie's being via the routes like this

Route::get('/set-session-test', function () { session(['user_check' => '4Me Session Alive']); return response('Session has been set. Check here'); });

Route::get('/get-session-test', function () { return 'Session Value: ' . session('user_check', 'Session NOT found'); });

I have also tried different setups in the .env .My login system uses OTP's to sign in these get sent via email of sms

0 likes
22 replies
JussiMannisto's avatar

What is your session driver? What do those tests of yours show: is the user_check value retrieved correctly or not?

419 is a CSRF protection error. If your sessions work but you get this error, you must make sure you're including a CSRF token on all POST requests.

EricMashiyane's avatar

this is my entire login blade I will also share the necessary .env information

@extends('layouts.app')

@section('content')

    <div class="auth-left">
        <div class="text-center mb-4">
<img src="{{ asset('assets/img/logo.png') }}" alt="4Me Logo" style="height: 120px;">
        <h2>Welcome Back</h2>
        <p>Log in to your existing 4Me Health account.</p>

        @if(session('success'))
            <div class="alert alert-success text-center">{{ session('success') }}</div>
        @endif
        @if(session('error'))
            <div class="alert alert-danger text-center">{{ session('error') }}</div>
        @endif

        <form method="POST" action="{{ route('login.post') }}" id="formAuthentication" onkeydown="checkEnterKey(event)">
            @csrf

            <input type="text" id="phone" name="phone" class="form-control @error('phone') is-invalid @enderror"
                   placeholder="Email / Mobile No." value="{{ old('phone') }}">
            @error('phone')<small class="text-danger">{{ $message }}</small>@enderror

            <!-- OTP -->
            <div id="otpField" style="display: {{ $errors->has('otp') ? 'block' : 'none' }};">
                <input type="text" id="otp" name="otp" class="form-control @error('otp') is-invalid @enderror"
                       placeholder="Enter OTP" value="{{ old('otp') }}">
                @error('otp')<small class="text-danger">{{ $message }}</small>@enderror

                <button type="submit" class="btn btn-primary w-100 mt-2" id="loginBtn">LOGIN</button>
            </div>

            <div id="error" class="text-danger text-center mb-2" style="display: none;"></div>
 
          
            
            <!-- GET OTP Button Wrapper -->
        </form>
    </div>

    <!-- RIGHT PROMPT -->
    <div class="auth-right">
        <div class="content">
            <h3 class="fw-medium mb-3">GET STARTED</h3>
            <p>Your health data, your story.<br>Manage it with 4Me.</p>
            <a href="{{ route('register') }}" class="btn-outline">SIGN UP FOR FREE →</a>
        </div>
    </div>
</div>

@endsection

EricMashiyane's avatar

the this is my .env data

APP_URL=https://www.4hr.co.za APP_TIMEZONE=Africa/Johannesburg

SESSION_DRIVER=file SESSION_DOMAIN=.4hr.co.za SESSION_COOKIE=laravel_session SESSION_SECURE_COOKIE=false SESSION_SAME_SITE=lax SESSION_LIFETIME=120

CACHE_DRIVER=file QUEUE_CONNECTION=sync FILESYSTEM_DISK=local

LOG_CHANNEL=stack LOG_LEVEL=debug

EricMashiyane's avatar

I send a login OTP to either an email address or cellphone. when I commit that OTP so that I can login, I get the Error 419 session expired.

JussiMannisto's avatar

You didn't say if your sessions work or not. Do you see the user_check value when you try to retrieve it?

Since you're using the file session driver, all session data will be written to the file storage. You have to make sure that the web server has write permissions on every directory within the storage directory. How that's done depends on your operating system and the web server you're using.

For more instructions, I'd need some details:

  • Operating system.
  • Which web server you're running: Artisan serve, Herd, Nginx, Apache, or something else.
EricMashiyane's avatar

Sorry, I appreciate your help, but my sessions don't seem to be working. I have tried to force check them explicitly by hardcoding the sessions in the routes. Then clear the cache and config, and test them if you follow this link, you will see what my struggle is.https://www.4hr.co.za/session-check

--I am using a company called, Xneelo runs a LAMP environment that includes Linux (Debian), Apache 2.4, MariaDB/MySQL, and PHP

JussiMannisto's avatar

@EricMashiyane The most common reason for file sessions not working is incorrect file and directory permissions. If the web server can't create or modify session files, then sessions won't work.

You need to make sure that everything under storage is owned by www-data, or whatever user Apache is running as. You can check the correct user and group by running this command:

grep APACHE_RUN /etc/apache2/envvars

Then you can set the storage owner and group by running this in the project root:

sudo chown www-data:www-data -R storage
EricMashiyane's avatar

@JussiMannisto Hello, I am relly stuck now. I dont know what else to do. I have deleted the instance I had running.I am redeploying it.I am using a not-so-old version of the code I had backed up.

EricMashiyane's avatar

@JussiMannisto yes, I did. However, there are some restrictions with the new host. I have two domains running this website. I had to move from my original host because they had disabled some php extensions that caused some APIs not to work. I have just tested upon re-enabling bcmath, I started experiencing this cookie issue on this domain https://www.4mehealth.co.za/test-session the bellow response is what I get , cookies are not being set.

{"session_id":"s2OFc4kzQjl71xBk5qXcKlCZJd4Rz9Jqp4PBleGU","csrf_token":"JUK4yqi9MJqPTdL9trcyv0wLx2hVRmHp0HeFv41F","session_data":{"_token":"JUK4yqi9MJqPTdL9trcyv0wLx2hVRmHp0HeFv41F","test_key":"working"},"cookie":null}

JussiMannisto's avatar

@EricMashiyane You're not explaining what's going on at all.

  • What is "cookie":null and where does it get its value?
  • What is "test_key":"working" and what does it signify?

Show the code, not just the output.

EricMashiyane's avatar

@JussiMannisto this is my login blade

@extends('layouts.app')

@section('content')

    <div class="auth-left">
        <div class="text-center mb-4">
<img src="{{ asset('assets/img/logo.png') }}" alt="4Me Logo" style="height: 120px;">
        <h2>Welcome Back</h2>
        <p>Log in to your existing 4Me Health account.</p>

        @if(session('success'))
            <div class="alert alert-success text-center">{{ session('success') }}</div>
        @endif
        @if(session('error'))
            <div class="alert alert-danger text-center">{{ session('error') }}</div>
        @endif

        <form method="POST" action="{{ route('login.post') }}" id="formAuthentication" onkeydown="checkEnterKey(event)">
            @csrf

            <input type="text" id="phone" name="phone" class="form-control @error('phone') is-invalid @enderror"
                   placeholder="Email / Mobile No." value="{{ old('phone') }}">
            @error('phone')<small class="text-danger">{{ $message }}</small>@enderror

            <!-- OTP -->
            <div id="otpField" style="display: {{ $errors->has('otp') ? 'block' : 'none' }};">
                <input type="text" id="otp" name="otp" class="form-control @error('otp') is-invalid @enderror"
                       placeholder="Enter OTP" value="{{ old('otp') }}">
                @error('otp')<small class="text-danger">{{ $message }}</small>@enderror

                <button type="submit" class="btn btn-primary w-100 mt-2" id="loginBtn">LOGIN</button>
            </div>

            <div id="error" class="text-danger text-center mb-2" style="display: none;"></div>
 
          
            
            <!-- GET OTP Button Wrapper -->
        </form>
    </div>

    <!-- RIGHT PROMPT -->
    <div class="auth-right">
        <div class="content">
            <h3 class="fw-medium mb-3">GET STARTED</h3>
            <p>Your health data, your story.<br>Manage it with 4Me.</p>
            <a href="{{ route('register') }}" class="btn-outline">SIGN UP FOR FREE →</a>
        </div>
    </div>
</div>

@endsection

JussiMannisto's avatar

@EricMashiyane You didn't answer my questions, you just posted irrelevant UI code. I can't help you because I don't know what's going on in your code. I'm not psychic.

EricMashiyane's avatar

@JussiMannisto so right at the bottom, is how I am testing if the App is able to generate a cookie.I am using an OTP to login instead of a password.

// ---------------------------- Route::get('/subscription', [SubscriptionController::class, 'index'])->name('subscriptions'); Route::get('/subscription', [SubscriptionController::class, 'index'])->name('subscriptions'); Route::post('/whisper-transcribe', [App\Http\Controllers\WhisperController::class, 'transcribe']); Route::post('/transcribe-audio', [WhisperController::class, 'transcribe']);

// ---------------------------- // MISCELLANEOUS (Cleanup) // ---------------------------- Route::get('/download-referral-letter/{id}', [HealthPractitionerController::class, 'downloadReferralLetter'])->name('download.referral'); Route::get('/subscriptions', [SubscriptionController::class, 'index'])->name('subscriptions'); Route::get('/subscribe/{id}', [SubscriptionController::class, 'subscribe'])->name('subscribe'); Route::post('/subscribe/{id}/confirm', [SubscriptionController::class, 'confirmSubscription'])->name('subscribe.confirm'); Route::get('/check-bcmath', function () { return function_exists('bccomp') ? 'BCMath is enabled ✅' : 'BCMath is NOT enabled ❌'; });

// Current GET route to show the form Route::get('/health-practitioner/patient-past-records/{id}', [HealthPractitionerController::class, 'patientPastRecords'])->name('patient.past.records');

// ADD THIS POST ROUTE to handle form submission Route::post('/health-practitioner/patient-past-records/{id}', [HealthPractitionerController::class, 'storeSession'])->name('patient.past.records.store');

Route::get('/test-session', function () { session(['test_key' => 'working']); return response()->json([ 'session_id' => session()->getId(), 'csrf_token' => csrf_token(), 'session_data' => session()->all(), 'cookie' => request()->cookie(config('session.cookie')), ]); });

JussiMannisto's avatar

@EricMashiyane So the session works now. You weren't stuck, this is just a different problem.

First check that your APP_URL is correct. You said your .env has https://www.4hr.co.za, but then linked a different site, https://www.4mehealth.co.za.

I checked the website, and it seems a bit broken. You have a stray @livewireScriptConfig text on top of the pages. On the registration page, you have a <script> tag before the <html> tag. You have <style> tags within <body>. The JS console shows multiple errors.

If your code outputs anything before response headers are set by Laravel, PHP will send its headers immediately, followed by the output. This prevents Laravel from sending additional headers, including Set-Cookie. If you have any bugs like that in your code, then that'll definitely stop cookies from working. So if you have echo or print calls, empty spaces before <?php tags or anything like that, that'll break headers and therefore cookies.

EricMashiyane's avatar

@JussiMannisto my system is not persisting sessions, lemme detail how it works

--- > a registered user enters their email or phone number, and the username or password arrives. But when committing the OTP in order to login, I get Error 419. I have been debugging why cookies don't persist. leading to an error 419.

---> The blade I have shared is to demonstrate that I use @csrf

JussiMannisto's avatar

@EricMashiyane Ok, so the test_key is being set on the same request as it was being echoed. The code is hard to read because it's unformatted. You should format code blocks with three backtics (```). I linked the instructions in a post above.

If cookies don't work, then sessions won't work either, including CSRF tokens. Check the APP_URL environment variable. Also check that you haven't set SESSION_DOMAIN.

A correction on my last point about leaking output: Laravel uses output buffering, so premature output shouldn't cause issues with headers.

EricMashiyane's avatar

@JussiMannisto Ahhhh I get it, so a lot of my problems are with the structuring of my app.blade.php? Cleaning is a start of sorting the issue out ? also remember having changed my app.blade.php before getting 419 error last week.

EricMashiyane's avatar

Hello, I am relly stuck now. I dont know what else to do. I have deleted the instance I had running.I am redeploying it.I am using a not-so-old version of the code I had backed up.

Snapey's avatar

you need to open your browser dev tools, look in application and see if the laravel session cookie is being set when you visit the site.

Also, make sure you dont have any dd() in your code. You may try this to debug but it stops session data being saved.

muhamadelsayed's avatar

This problem happened also for me , it was solved when I knew that I must send only one csrf token as I was sending more than one per form

Please or to participate in this conversation.