Home » Errors » How to Fix TokenMissmatch Exception in Laravel

How to Fix TokenMissmatch Exception in Laravel

The TokenMissmatchException can appear when you send any POST request to a web route without a CSRF protection token or with an outdated one. CSRF protection is enabled for all web routes by default. It is required to protect your forms from malicious actions.

In this article, I will show multiple cases when you can encounter the exception and explain how to fix TokenMissmatch exception in Laravel.

What is CSRF vulnerability

Imagine, that you have a form where a user can send messages to other users. The form has two fields: “text” and “to”, where users can specify the message text and the recipient. Your application has the https://your_app/message POST endpoint which is used as action for this form.

<form action="{{route('message')}}" method="POST"> <input type="text" name="text"/> <input type="text" name="to"/> <button type="submit">Send</button> </form>

Someone can create an auto-submitting form on a third-party site which refers to your endpoint. For example:

<form action="https://your_app/message" method="POST"> <input type="hidden" name="text" value="A spam message" /> <input type="hidden" name="to" value="recipient"> </form> <script> document.forms[0].submit(); </script>

When you or another user open this malicious page, your application will automatically send the spam message to the recipient. To prevent this, you should ensure that the request came from your application. Laravel does this automatically by generating a CSRF Token and storing it in the user’s session, you should send it for all POST requests except for API.

How to Fix TokenMissmatch Exception in Laravel

1. When a Token is Outdated

As I mentioned earlier, you can encounter the TokenMismatch exception if the CSRF token is missing or if you provide an outdated token. In the second case, simply update the page with the form, to get a new one. Laravel stores the token in the user’s session, which has a default duration of 120 minutes. If you attempt to submit a POST form that was opened more than two hours ago, you will get this error or the message Page Expired.

You can increase the session lifetime by using the SESSION_LIFETIME variable in the .env file:


Alternatively, you can open the config/session.php file, find the lifetime line, and change the default value of 120 minutes to your desired value:

return [ //... "lifetime" => env("SESSION_LIFETIME", 120), //... ];

1. When a Token is Missed in Forms

Your form must contain the hidden _token field with the CSRF token. You can check it using code inspection tools in your browser:

You can add the CSRF token into a form in multiple ways. First, you can use the @csrf blade helper which generates a hidden field:

<form method="POST" action="/profile"> @csrf </form>

Also, you can get just the token using the csrf_token() method and add the hidden input manually:

<form method="POST" action="/profile"> <input type="hidden" name="_token" value="{{ csrf_token() }}" /> </form>

After adding this field, your form will work as expected.

2. When Token is Missed in Ajax

If you get this error in AJAX requests, you probably call web routes from JavaScript. It is a bad solution and you should think about using API routes instead of web. API routes do not have CSRF protection and can have authentication with Sanctum or be public if necessary.

If you want to continue using web routes in Ajax, you should send a CSRF token in the X-CSRF-Token header. For example:

fetch("{{route('message')}}", { method: "POST", headers: { "X-CSRF-Token": "{{csrf_token()}}", }, }) .then(function (response) { return response.json(); }) .then(function (data) { console.log(data); });

Also, you can disable CSRF protection for a specific route. You can simply disable the VerifyCsrfMiddleware for a specific route or a group of routes using withoutMiddleware() method:

Route::post("/message", function () { //.... })->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class);

Also, you can modify the app/Http/Middleware/VerifyCsrfMiddleware class and add your routes into the $except array:

class VerifyCsrfToken extends Middleware { protected $except = [ '/message' ]; }

Wrapping Up

In this short article, I have explained how to fix TokenMissmatch Exception in Laravel. It is very important to have CSRF protection for all your forms and use it properly.

Your Reaction

Leave a Comment