Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

AliMalik's avatar

How CsrfToken works

I am having a continuous issue with csrf token. When i post my from i always get this annoying token mismatch exception. How actually these token works and how can i overcome this issue. This is happening on the form post where user is already logged in and updates his profile information.

0 likes
32 replies
dishark's avatar
<input type="hidden" name="_token" value="{{ crsf_token() }}" />
dishark's avatar

the value doesn't rendered. you need to print this function:

csrf_token()
RachidLaasri's avatar

If you are using the form builder

{!! Form::open() !!}

{!! Form::close() !!}

This will handle creating CSRF token for you, if not, you need to add a hidden input to your form with the value of the token that laravel generates.

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
AliMalik's avatar

Yes i am using form builder , and it handles that ( i can see token in the page source ) but still it says token mismatch exception

AliMalik's avatar

I tried all of these: 1 ) Manually adding hidden field of token. 2 ) Adding token field as a meta tag in my layout page But still it shows same error..

AliMalik's avatar

No not through ajax.. simple form submission ,

{!! Form::open(['method'=>'POST','url'=>'wizard/js/personal','novalidate'=>'novalidate','id'=>'jsPersonal-form','class'=>'ali-form']) !!}
And it creates token automatically , but when i hit submit button this error is thrown
                
bashy's avatar

Open your browser's developer tools window and navigate to the Network tab. When you press submit, check the POST entry and take a look at the params of the POST. This will show you what data was sent, if you do not see a _token, it wasn't sent.

Once you confirm that's there, we'll go from there.

AliMalik's avatar

There is _token present in form data and exactly set to the value that i can view while inspecting the source of page, status code is 500

Remote Address:[::1]:8000
Request URL:http://localhost:8000/wizard/js/personal
Request Method:POST
Status Code:500 Internal Server Error
_token:OVEFrXK9gZuWsJYP8OXFRWu54jR2FMUVKKs9KsSz
bashy's avatar

You could be doing something not related directly to CSRF token. Can you show the code used in the form? Have you got a live dev link?

nolros's avatar

@AliMalik what is your session lifetime set to in your session.php config file? Could be that your session lifetime cycle is expiring. If you session expires the CSRF token will mismatch. In AngularJS fo example you can look for this and redirect to login.

Example, if you set the value below to 1 then every minute it will expire.

    /*
    |--------------------------------------------------------------------------
    | Session Lifetime
    |--------------------------------------------------------------------------
    |
    | Here you may specify the number of minutes that you wish the session
    | to be allowed to remain idle before it expires. If you want them
    | to immediately expire on the browser closing, set that option.
    |
    */

    'lifetime' => 120,
AliMalik's avatar

This is my form that gives me mismatch error upon submission

{!! Form::open(['method'=>'POST','url'=>'wizard/js/personal','novalidate'=>'novalidate','id'=>'jsPersonal-form','class'=>'ali-form']) !!}
                    <header>Personal Details
                        <div class="steps">
                            Steps 1 - 5
                        </div>
                    </header>

                    <fieldset>

                        <div class="row">
                            <div class="col-sm-6 col-sm-offset-1">
                                <div class="picture-container">
                                    <div class="picture">
                                        <img id="wizardPicturePreview" class="picture-src" title="" src="{{asset('images/wizard/default-avatar.png')}}">
                                        <input id="wizard-picture" type="file">
                                    </div>
                                    <h5>Choose Picture</h5>
                                </div>
                            </div>
                            <section class="col col-6">
                                <label class="input">
                                    <input name="firstname" placeholder="First name" type="text">
                                    <b class="tooltip tooltip-bottom-right">Your First Name</b>
                                </label>
                            </section>
                            <section class="col col-6">
                                <label class="input">
                                    <input name="lastname" placeholder="Last name" type="text">
                                    <b class="tooltip tooltip-bottom-right">Your Last Name</b>
                                </label>
                            </section>
                        </div>

                        <div class="row">
                            <section class="col col-6">
                                <label class="input">
                                    <i class="icon-append fa fa-calendar-o"></i>
                                    <input id="date" name="dateofbirth" placeholder="Date Of Birth" type="date">
                                    <b class="tooltip tooltip-bottom-right">Your Date of Birth</b>
                                </label>
                            </section>
                            <section class="col col-6">
                                <label class="input">
                                    <i class="icon-append fa fa-credit-card"></i>
                                    <input id="cnic" name="cnic" placeholder="CNIC" type="text">
                                    <b class="tooltip tooltip-bottom-right">Your CNIC</b>
                                </label>
                            </section>
                        </div>

                        <div class="row">
                            <section class="col col-6">
                                <label class="select">
                                    <select name="location">
                                        <option value="0" selected="selected" disabled="disabled">Location</option>
                                        <option value="1">Islamabad</option>
                                        <option value="2">Lahore</option>
                                        <option value="3">Other</option>
                                    </select>
                                    <i></i>
                                </label>
                            </section>
                            <section class="col col-6">
                                <label class="select">
                                    <select name="gender">
                                        <option value="0" selected="selected" disabled="disabled">Gender</option>
                                        <option value="1">Male</option>
                                        <option value="2">Female</option>
                                        <option value="3">Other</option>
                                    </select>
                                    <i></i>
                                </label>
                            </section>
                        </div>

                        <div class="row">
                            <section class="col col-6">
                                <label class="select">
                                    <select id="language" name="language" multiple>
                                        <option value="1">Urdu</option>
                                        <option value="2">Punjabi</option>
                                        <option value="3">English</option>
                                    </select>
                                </label>
                            </section>

                            <section class="col col-6">
                                <label class="input">
                                    <i class="icon-append fa fa-mobile"></i>
                                    <input id="phone" name="phone" placeholder="Phone No" type="">
                                    <b class="tooltip tooltip-bottom-right">Phone Number for Sending you Notifications</b>
                                </label>
                            </section>
                        </div>

                        <section>
                            <label class="textarea">
                                <i class="icon-append fa fa-comment"></i>
                                <textarea placeholder="About Me" name="aboutme" rows="4" onKeyDown="limitText(this.form.aboutme,this.form.countdown,250);" onKeyUp="limitText(this.form.aboutme,this.form.countdown,250);"></textarea>
                                <b class="tooltip tooltip-bottom-right">Your Introductory Text for Profile viewers</b>
                                <p size="1"> You have <input readonly type="text" name="countdown" size="3" value="250" style="
                                    padding-left:5px; border:none;">characters left.</p>
                                <!-- <font size="1"> You have <input readonly type="text" name="countdown" size="3" value="250" style="padding-left:5px;"> characters left.</font> -->
                            </label>
                        </section>

                    </fieldset>
                    <footer>
                        <button type="submit" class="button">Next</button>
                    </footer>
                {!! Form::close() !!}
AliMalik's avatar

@nolros this is my sessions.config file already set to 120 mins:

    'lifetime' => 120,

    'expire_on_close' => false,

jimmck's avatar

Why not verify your code is working and turn of CSRF.

Go to App\Http\Kernel.php and comment out the CSRF service...

<?php namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel {

    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
        'Illuminate\Cookie\Middleware\EncryptCookies',
        'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
        'Illuminate\Session\Middleware\StartSession',
        'Illuminate\View\Middleware\ShareErrorsFromSession',
        'App\Http\Middleware\VerifyCsrfToken',
    ```


and give your form a go.

AliMalik's avatar

Does It mean issue is with sessions or csrf.. ?

bashy's avatar

What session driver are you using? Don't think you posted it above did you?

jimmck's avatar

@ AliMalik So after you turned off middleware your form post worked? I am in US so we got a time diff. If yes you are either not sending proper token or getting from your session? Can you add _token as hidden form field? Here is a quick way I use for testing/ not prod. I have a Get call to grab a new token.

 \Route::get('token', function () {
       return csrf_token();
   });

Call this URL and put the token in your hidden field and POST your form. Of course turn on middleware. I send JSON data structs to a controller over POST so I just add token each time.

    //fyi("inside call...");
    // how do we check the url is correct? timeout causes problems.
    // the busy flag needs to be static for the class.

    // make sure if callData is an object we make it an empty object.
    // we do this so we can add _token to it.

    if (callData == "") {
        callData = {};
    }
    this.busy = true;
    callData['_token'] = this.csrf_token;
    fyi('Post token [' + callData['_token'] + ']');
    $.myPost(url, callData, this, this.handlePost, this.postError, this.timeout, this.async);
AliMalik's avatar

@bashy This is my session driver:

    'driver' => env('SESSION_DRIVER', 'file'),
AliMalik's avatar

@jimmck Yes i manually added the token as a hidden field in my form and posted , but this token is same as created by form builder.

bashy's avatar

Must be something up with your session data, that line you pasted above doesn't show it 100%, do you have SESSION_DRIVER environment var set?

AliMalik's avatar

This is my sessions file

return [

    'driver' => env('SESSION_DRIVER', 'file'),
    'lifetime' => 120,
    'expire_on_close' => false,

    'encrypt' => false,

    'files' => storage_path().'/framework/sessions',

    'connection' => null,
    'table' => 'sessions',

    'lottery' => [2, 100],

    'cookie' => 'laravel_session',
    'path' => '/',

    'domain' => null,

    'secure' => false,

];
And yes env variable is set to file

SESSION_DRIVER=file

bashy's avatar

Have you checked if it's saving them okay? Does authentication work fine?

AliMalik's avatar

Yes Authentication is working fine on all other pages , i am stuck on this specific form. Also by checking network tab of dev tools as you guided earlier i see that it is maintaining sessions and csrf token both

Request Cookies                 930             
XSRF-TOKEN  eyJpdiI6IlJjTWRURmg4ZnlFN0JvTXk1MUFVNUE9PSIsInZhbHVlIjoieUdRblwvQnFwZEx6VlwvTk82MWs1ZDRRbTZjVjJoSWlWZzBXSjRHaUhqK3gwNjhCRG5nZmw3RStFYU1sUCt2cXVkcVBHblZtN05EdGx5RURQREdZRU94UT09IiwibWFjIjoiZDQ3NjhiMWE1ZmQ3MzZiNmUxMDA1ZjIyMjhlZDg1MjlkNjIxOTkzZjg2MzljNDUzNmVkMWY5YzYwZjA1YzBlZSJ9    N/A N/A N/A 289             
laravel_session eyJpdiI6Imw3bjdsV0Q3T1BvYnNQeUVxRUFLZnc9PSIsInZhbHVlIjoieWw4b1JmRWZKREhEM0l0ZEU3c0xyek1MRUdpSFBHdmsrTHBvQ29jTDg3SnE3MmE0QjdhMU1xSEpuSzJGRm8yYm5WNVdFcGl2Y0pZNGJFXC81VWZ0RmhBPT0iLCJtYWMiOiJlYWU5OWNkZjc4N2Y2ZDVjMTUxMjNjNDhmYWUyNjJmYzE4ZDBmNTNiYzMzNzU1OWQ0ZTc3MmVkZjFjYTZhYTM2In0%3D  N/A N/A N/A 294             
remember_js_5ab1837e91245bf513442c708b50254d    eyJpdiI6IklxemR2ckF5c0xtTFNERDhPODl3TUE9PSIsInZhbHVlIjoiZGZGRGtwNzBhcGNMdGdHOHBLRG56bW1oTFhyN2ZHNmNsVndXMGkrblBjWE5mekdKWk9PUmxGVkZMZngzYklqOExCQjg2SnhacWJTbEdNZzNHQzF4b2k2NUZoTDJiUzQ1dUkzNGE2Z0dMRnc9IiwibWFjIjoiYTgzZGFkNjZhNDE4ZTk1NDI0ZDlmZDcwODA4YmE2N2IyNzExZjc0OGJhOWJiN2NlNTI3NWM2MzYzYWM1MjY5MiJ9    N/A N/A N/A 347             
Response Cookies                    722             
XSRF-TOKEN  eyJpdiI6InlWUXlFTzRjYUxsamh4RTNPcm16dHc9PSIsInZhbHVlIjoidkpZWHRUM3pZMGdwd3NVUGE0a3RHc29jS0czS1wvb1wvY2NmNk82Rk5yY1wvRGRvd0p2SkdKS3lZbEMzWVJPZjhxKzY2UXI0emR5YlNBaUpwTTRaXC9XSVJRPT0iLCJtYWMiOiIyMjkzMTE3MzExYWExM2ZmNjNhNzFlMjlhMWMzNmNjOGU1YWZkYzVhNzViNzllMWRiM2U1MDJkNDhiYmFhZjQ5In0%3D      /   2.0 hrs 355             
laravel_session eyJpdiI6IlJtdUZBdURleUVzR0dadllGbXZzZkE9PSIsInZhbHVlIjoiZ2l4QjBZcEZZR3BlVjNhdTBmTmJUamVNTW1UZm1rYWpFemZoNG1kQUJnMHplbkhPbXFjdW54Vno2UFlkWjJyRzQyMFJySGVtUHQ0Y1oyOElxOTk3VWc9PSIsIm1hYyI6ImRlMzAzNDBkMDBlYjliMTY5YjliNjc2Mjc5ZmFjZGFjMmVkZTVmNTI5NmY2MTQ0YTNiYjlmNWU0NjdmNzliMDEifQ%3D%3D        /   2.0 hrs 367 ✓           
 
bashy's avatar

Are you sure it's being sent by JS? I've never had a problem with CSRF tokens...

AliMalik's avatar

Me to bro just this specific case dnt know why

raomaster's avatar

you can try :

<form action="{!! url('your/page') !!}" method="POST">
                <input type="hidden" name="_token" value="{!! csrf_token() !!}">
 </form>
AliMalik's avatar

After so much of testing and tries to solve it, i cannot solve the issue, but when i switched from laravel dev server to my EasyPhp local server it stopped throwing me those annoying mismatch errors. Any note on that..??

Next

Please or to participate in this conversation.