68

I'm new with Laravel and I have a problem which I don't understand. I have а log form in my project and my method is POST. When I try a request the result is:

'The page has expired due to inactivity. Please refresh and try again.'

But if I change the method to GET, It works fine.

Can someone tell me why is that and how to fix it? because of course I need POST method.

Udhav Sarvaiya
  • 9,380
  • 13
  • 53
  • 64
Svetlozar
  • 967
  • 2
  • 10
  • 23

32 Answers32

176

This problem comes from the CSRF token verification which fails. So either you're not posting one or you're posting an incorrect one.

The reason it works for GET is that for a GET route in Laravel, there is no CSRF token posted.

You can either post a CSRF token in your form by calling:

{{ csrf_field() }}

Or exclude your route (NOT RECOMMENDED DUE TO SECURITY) in app/Http/Middleware/VerifyCsrfToken.php:

protected $except = [
    'your/route'
];
Erik Baars
  • 2,278
  • 1
  • 8
  • 14
  • 1
    For anyone else viewing this, you can also put a meta tag in your site header which will be used with most requests. – parker_codes Apr 28 '18 at 05:36
  • @Erik I'm not really sure if the 2nd approach is fine. If we exclude a route in `VerifyCsrfToken.php` the route will be vulnerable to CSRF attack, I think – Hiroki Jun 07 '18 at 05:36
  • The second approach WOULD pose a security risk, this is true. However, there are use cases where you might not want to do CSRF verification. Such as AJAX calls. – Erik Baars Jun 20 '18 at 12:57
  • @ErikBaars You still want to use CSRF if you're doing AJAX requests from an SPA to your backend. I do this with Laravel by getting the CSRF token on the initial request for the SPA and then maintaining an updated token by getting it from response headers using an HTTP interceptor. – Colin Jul 26 '18 at 13:11
  • In my case the Laravel Auth login system was giving the "expire page error". I had to check my /resources/views/auth/login.blade.php to have this line: {{ csrf_field() }} . thats it! – gtamborero Sep 12 '18 at 14:46
  • @ErikBaars After excluding the route it is throwing a 404 error. – golchha21 May 08 '19 at 16:05
  • I have added route in exception because post request is coming from payment gateway. – Avnish Tiwary Jul 05 '19 at 04:52
35

In my case, I've got the same error message and then figured out that I've missed to add csrf_token for the form field. Then add the csrf_token.

Using form helper that will be,

{{ csrf_field() }}

Or without form helper that will be,

<input type="hidden" name="_token" value="{{ csrf_token() }}">

If that doesn't work, then-

Refresh the browser cache

and now it might work, thanks.

Update For Laravel 5.6

Laravel integrates new @csrf instead of {{ csrf_field() }}. That looks more nice now.

<form action="">
   @csrf
   ...
</form>
Maniruzzaman Akash
  • 4,610
  • 1
  • 37
  • 34
7

Anytime you define an HTML form in your application, you should include a hidden CSRF token field in the form so that the CSRF protection middleware can validate the request. You may use the csrf_field helper to generate the token field:

<form method="POST" action="/profile">
    {{ csrf_field() }}
    ...
</form>

It doesn't work, then Refresh the browser cache and now it might work,

For more details open link :- CSRF Protection in Laravel 5.5

UPDATE:

With Laravel 5.6 using Blades templates, it's pretty easy.

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

For more details open link :- CSRF Protection in Laravel 5.6

Udhav Sarvaiya
  • 9,380
  • 13
  • 53
  • 64
  • This is not the perfect solution. Because in case of User, how they will know that they have to delete the cache. – Naisarg Parmar Mar 14 '18 at 06:41
  • When we update our application, a browser may still use old files. If you don’t clear your cache, Old files can access problems when you apply. for more details read this https://laravel.com/docs/5.5/csrf – Udhav Sarvaiya May 17 '18 at 09:13
6

Verify that your config/session.php file contains this line

'domain' => env('SESSION_DOMAIN', null),

Then remove the SESSION_DOMAIN line in your .env file

  • 2
    Would you be able to elaborate on this a bit? Why, what does it do ? – callmebob Jul 13 '19 at 09:19
  • 1
    Doesn't that in essence amounts to this code: `'domain' => null,` ? – matthiku Mar 24 '20 at 15:52
  • Furthermore, my first conclusion that this solved my problem turned out to be false. It was actually my browser cache that was the issue. I first opened this page in an incognito window of the browser and then it worked. – matthiku Mar 24 '20 at 16:12
4

In my case , I added ob_start(); at the top of my index.php on server and everything seems to be working fine.

4

Excluding URIs From CSRF Protection:

Sometimes you may wish to exclude a set of URIs from CSRF protection. For example, if you are using Stripe to process payments and are utilizing their webhook system, you will need to exclude your Stripe webhook handler route from CSRF protection since Stripe will not know what CSRF token to send to your routes.

Typically, you should place these kinds of routes outside of the web middleware group that the RouteServiceProvider applies to all routes in the routes/web.php file. However, you may also exclude the routes by adding their URIs to the $except property of the VerifyCsrfToken middleware:

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'stripe/*',
        'http://example.com/foo/bar',
        'http://example.com/foo/*',
    ];
}
Kamlesh
  • 5,233
  • 39
  • 50
3

i had same problem. use 'clear browsing data' in chrome. maybe solve your problem.

3

This happens because you are using the default CSRV middleware from Laravel's installation. To solve, remove this line from your Kernel.php:

\App\Http\Middleware\VerifyCsrfToken::class,

This is fine if you are build an API. However, if you are building a website this is a security verification, so be aware of its risks.

3

Tried different solutions to solve the problem for several weeks without success.

The problem I was facing was caused by upgrading from laravel 5.0 to 5.5 and forgot to update config/session.php

If anyone is facing the problem, try to update the config/session.php to match the version on Laravel you are running

Rayton Kiwelu
  • 401
  • 4
  • 4
  • I was searching for hours, this was also my exact problem, but I upgraded to 5.7. Thanks for sharing! – Daantje Dec 29 '18 at 21:32
3

I had the same problem, I have tried many solutions. but none worked for me. then I found out that for some reason I was using this in my .env file:

SESSION_DOMAIN= myapp.me

and as soon as I put it back to null, everything worked just fine.

2

if your config is set: SESSION_DRIVER=file you have to check if your session directory is writable. Check storage/framework/session

zizoujab
  • 7,603
  • 8
  • 41
  • 72
  • Also check if your *disk is full*. Took me hours to realize that it can't write the session file to disk... – bosch Jul 05 '19 at 11:18
2

Place {{csrf_field()}} Into your form tag

enter image description here

Wael Assaf
  • 1,233
  • 14
  • 24
2

If you have already included the CSRF token in your form. Then you are getting the error page possibly because of cache data in your form.

Open your terminal/command prompt and run these commands in your project root.

  1. php artisan cache:clear
  2. php artisan config:clear
  3. php artisan route:clear
  4. php artisan view:clear,

Also try to clear the browser cache along with running these commands.

Udhav Sarvaiya
  • 9,380
  • 13
  • 53
  • 64
2

First, include csrf in your form.

{{ csrf_field() }}

if the problem didn't solve, then use ob_start(); at the very start of index.php.

<?php ob_start();
DJo
  • 2,133
  • 4
  • 30
  • 46
Abid Shah
  • 325
  • 3
  • 5
2

In my case, there was 'space' before <?php in one of my config file. This solved my issue.

1

Just place this code inside the form

<input type = "hidden" name = "_token" value = "<?php echo csrf_token() ?>" />
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Manu Joseph
  • 389
  • 4
  • 10
1

I was facing the same error so i just removed this line from my .env file

SESSION_DRIVER=yourwebsite.com

Akash Sethi
  • 184
  • 1
  • 4
  • 15
1

Still anyone have this problem, use following code inside your form as below.

 echo '<input type = "hidden" name = "_token" value = "'. csrf_token().'" >';
Sineth Lakshitha
  • 619
  • 6
  • 14
1

Just add @csrf inside your form tag.

Or you can include csrf_token in the header to send it with every request.

CKE
  • 1,533
  • 19
  • 18
  • 29
Shaz
  • 419
  • 3
  • 11
1

if you need to change form action with Javascript you will have the same problem

1.first you need to use instead of {!!Form::open() !!} {!! close() !!} in laravel
2.second you most begin your action with https://www.example.com +your Route

Do not Forget www in your url!!!

0

In my case the same problem was caused because I forgot to add > at the end of my hidden input field, like so: <input type="hidden" name="_token" value="{{ Session::token() }}"

So, I fixed it by adding it:

<input type="hidden" name="_token" value="{{ Session::token() }}">
Kaloyan Drenski
  • 950
  • 1
  • 13
  • 18
0

It's Funny but it works for me. i realised this is Caused because of default HTML TAG in laravel code. Use /* */ or {{-- --}} instead

Or Try to Remove Recently Html Coment in you code... Or change Html Comment to Php Comment... Or try to run Any Worng artisan command like php artisan clean browser And See if it output any HTML Commented data along with it error...

samtax01
  • 834
  • 9
  • 11
0

We got it working by copying the routes from Router.php instead of using Auth::routes(), these are the routes you need:

Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController@login');
Route::post('logout', 'Auth\LoginController@logout')->name('logout');

// Registration Routes...
Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
Route::post('register', 'Auth\RegisterController@register');

// Password Reset Routes...
Route::get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
Route::post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
Route::get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
Route::post('password/reset', 'Auth\ResetPasswordController@reset');
Miguel Stevens
  • 8,631
  • 18
  • 66
  • 125
0

I know this question has been satisfactorily answered, but I wanted to mention a fix that worked in my case. I added {{ csrf_field() }} and it still didn't work.

Then I remembered that I blocked all cookies for development purposes, which can be nice when you change the page and want to refresh it.

Once I changed the settings to stop blocking all cookies in MS Edge browser the problem went away.

Agaz Wani
  • 5,514
  • 8
  • 42
  • 62
0

my problem solved by just adding @csrf in form tag

Laravel 5.6 doesn't support {{ csrf_field() }} just add @csrf in place of {{ csrf_field() }}

larvel_fix_error.png

Virb
  • 1,639
  • 1
  • 16
  • 25
mysticmeelone
  • 13
  • 1
  • 7
0
  1. It may be csrf token do not have in your form. You have to use @crsf or {{ csrf_field() }}

  2. If you are use csrf on your form. It may be cache. Clear your app cache.

    php artisan cache:clear
    php artisan view:clear
    php artisan cache:clear
    

    And clear your browser cache.

  3. If errors again show you, then create a new key

    php artisan key:generate
    
Udhav Sarvaiya
  • 9,380
  • 13
  • 53
  • 64
Turan Zamanlı
  • 3,828
  • 1
  • 15
  • 23
0

If anyone still looking for an answer to this issue. For me it happens when I'm switching between local and production server and I'm logged on both sites. To fix the issue, just clear the session.

just set the 'expire_on_close' => true in config\session.php and restart your browser

user1917451
  • 169
  • 2
  • 3
  • 11
0

I recently went through this problem, tried all the solutions proposed here (and the internet) without success for 5 days.

In my case my environment:

Laravel: 5.5

PHP: 7.2

SSL: production

Apache

CENTOS

The problem is that I had automated the deployment using the git --bare repository with ansimble.

And all folders when pushing were with permission 0775 (inherited from the git user). When ansinble was run it replicated this permission to all folders. When composing install for example, all vendor folders also had this permission.

The csrf, has a policy of blocking what is considered insecure, especially if you use an encrypted environment (SSL).

I only realized the problem when I decided to carry out the deployment manually, zipped the project, uploaded it, unzipped it and ran the commands to generate the caches and dependencies. And then I realized that this way all folders were with permission 0755 (inherited from the system user). And this is the default permission that is considered safe.

0

In my case, it seems to be an issue in my web browser (Firefox for Android) or my smartphone with full storage. In another browsers and devices it works. By the way, the issue happens only when I send files through the form, I realized I currently can't upload files from my smartphone through this browser in any websites like https://filebin.net.

cawecoy
  • 2,359
  • 4
  • 27
  • 36
0

This is very simple for me. maybe the sessions folder is missing in storage/framework/sessions

user3389579
  • 291
  • 2
  • 4
0

Some time its issue with the server storage. In my case server storage was full so it could not write any session to file.So freeing out some server storage solved the issue. Also sometimes it the issue of csrf if we forget to include csrf in post field.

-3

Go into App/Kernel.php and comment \App\Http\Middleware\VerifyCsrfToken::class.

picsoung
  • 6,314
  • 1
  • 18
  • 35
Aarif
  • 9