If you submit a form in a Laravel application via POST and see the error 419 Page Expired, it’s typically because there was a CSRF token mismatch.
To address this issue, make sure your form has a hidden field called _token
that has its value set to the invocation of Laravel’s built in csrf_token()
helper method.
You can either do this manually:
<form method='post' action='/process'>
<!-- THIS IS THE FIELD YOU NEED: -->
<input type='hidden' name='_token' value='{{ csrf_token() }}'>
<label for='email'>Email:</label>
<input type='email' id='email' name='email' value='demo@gmail.com'>
<input type='submit'>
</form>
Or if you're using Laravel’s Blade templating language, you can generate the field using the @csrf
directive:
<form method='post' action='/process'>
<!-- THIS WILL GENERATE THE FIELD YOU NEED: -->
@csrf
<label for='email'>Email:</label>
<input type='email' id='email' name='email' value='demo@gmail.com'>
<input type='submit'>
</form>
Because the field is hidden, you won’t see it in the browser, but you should see it if you view the page source:
CSRF Tokens are only validated for forms submitted via POST (or spoofed via PUT, PATCH or DELETE). CSRF tokens are not validated for forms submitted via GET.
Other possible causes
The token was set, it just expired.
If a form is loaded and then not submitted for a while, it could be that the token has expired. When this happen, simply refreshing the page before submitting the form should resolve the issue. You can also check the config value for lifetime
in /config/sessions.php
to see how long the session is allowed to remain idle before it expires. If necessary, you can up this value.
There’s a middleware conflict
If you have custom middleware or third-party packages that modify the request flow, ensure that they are not interfering with the CSRF token verification process. One place to look for modifications is your app/Http/Middleware/VerifyCsrfToken.php
file.
SSL Termination is causing issues
If you are handling SSL requests via a load balancer or reverse proxy, it can cause issues with CSRF token validation. Try accessing your application directly without SSL termination to see if it resolves the problem.
What is CSRF?
CSRF, or Cross-Site Request Forgery, is a type of web application vulnerability where a user unintentionally runs a script in their browser that takes advantage of their logged in status on a target site.
For a bare-bones example, imagine your application has a form that POSTs to http://yourdomain.com/users/delete
, which will trigger the deletion of a logged-in user's account.
Now imagine a hacker (perhaps a nefarious competitor?) has dug through your source code to find this URL and wishes to trick your users into deleting their accounts. The hacker does this by creating a form on their site which appears innocuous, but actually triggers the /users/delete
route on your site.
<form method='POST' action='http://yourdomain.com/users/delete'>
<input type='submit' value='Click to claim your free prize!'>
</form>
The hacker would then try to get your users to view the page on their site and submit the form (perhaps through a phishing email campaign).
This is an example of a cross-site request forgery— the hacker’s site is trying to submit a request to your site. If your users fall for this trick, and if they’re accessing the hacker’s site via a browser that’s also logged into your site, bad stuff can happen.
To prevent CSRF attacks you want to verify that the origin of requests on your site are coming from within your site. This is done by sending a unique, encrypted token with each form submission, the CSRF token.
When the form submission is received by your application, Laravel automatically checks the token to make sure it’s valid, thereby verifying the form submissions is legitimate.