MakkyNZ
MakkyNZ

Reputation: 2255

Laravel session id changes with each request

I have a Laravel 5.0 site where the frontend JS makes a lot of ajax calls to the backend Laravel code. I've noticed that on each ajax request I'm getting a new "laravel_session" cookie value in the response everytime. I'm guessing that this is some security mechanism to protect against session hijacking.

However I think this is causing an issue with my site, as my ajax calls often happen in parallel, not sequentially. I don't wait for the response before firing the next call.

Consider this scenario

. Ajax call 1 - request - laravel_session cookie = '1234'

. Ajax call 1 - response - laravel_session cookie = '2345'

. Ajax call 2 - request- laravel_session cookie = '2345'

. Ajax call 3 - request- laravel_session cookie = '2345'

. Ajax call 2 - response - laravel_session cookie = '3456'

. Ajax call 3 - response - session not longer valid

Is there any way around this?

I should also note that sessions are set to expire in the config/session.php as 'lifetime' => 120,

enter image description here

config/session.php

Upvotes: 13

Views: 14410

Answers (6)

Snapey
Snapey

Reputation: 4110

Incase this affects anyone else. My customer had provided a snapshot of their data, and so I was using Carbon::setTestNow to pretend that the current time is in a period supported by the customer's data.

This caused session cookies to be created with a timestamp in the past so that they were immediately expired by the browser.

For my simulations, I could call Carbon::setTestNow() again after my database queries to avoid the issue.

Wasted a few hours on it though!

Upvotes: 0

kodmanyagha
kodmanyagha

Reputation: 1005

There are some important things about sessions. First is cookie time. If your Laravel app's timezone is UTC but your computer's timezone is +3 then if you set your cookie lifetime 120 (two hours) then cookie will deleted by browser immediatelly. You must increase your cookie lifetime.

Other option is encryption. Cookies are always encrypted. If you set encrypt=true in sessions.php file storage/framework/sessions folder will be encrypted. Sometimes this causes problem. If session doesn't keep then try to set encrypt to false. After that you can see session files are unencrypted and they have 'serialized' text. Then you can see your session variables in there.

Other option is domain variable in sessions.php file. You must set it correctly or leave it null. Domains must not have http(s):// at first. Write only domain in there (for example yourdomain.com, yourdomain.test, yourdomain.host, www.yourdomain.com, subdomain.yourdomain.com etc...).

Other option is about driver. If you set it to database then you must be sure your table columns have enough size for storing big session data. If you set it to file then you must be sure that storage/framework/sessions folder is writable and readable.

And there is a "small" (I think so important) trick. Don't use general keywords in session. For example don't use 'token' key. Use specific names for session. This is wrong: session(['token' => $result->token]), but this is better: session(['backend_remote_token' => $result->token])

Rock'n roll...

Upvotes: 0

Hussam Abd
Hussam Abd

Reputation: 21

I had the same issue, I tried a lot of solutions and nothing worked for me.

My case: The token keeps changing on every request only when the session driver is set to database, and it works just fine on file and Redis driver.

After a lot of debugging, I found that the issue was not with session config, it was from the payload column in the session table in the DB.

I changed the payload column from text to longText, and it worked!

Upvotes: 1

Shan
Shan

Reputation: 41

The same issue happened with me and it was later identified that I was using

protected $middleware = [
     \Illuminate\Session\Middleware\StartSession::class,
     \Illuminate\View\Middleware\ShareErrorsFromSession::class
];
protected $middlewareGroups = [
     'web' => [
          \Illuminate\Session\Middleware\StartSession::class,
          \Illuminate\View\Middleware\ShareErrorsFromSession::class
     ]
]

in both $middleware and in $middlewaregroups because of which it was creating a new session id in movement between different routes.

Upvotes: 1

malhal
malhal

Reputation: 30801

You are right it is a security mechanism. To disable it for testing, in Kernel.php comment out this line:

\App\Http\Middleware\EncryptCookies::class

Then you will see the session ID in your cookie viewer and it doesn't change.

You can Google for HTTP encrypted cookies to learn about the practice. There is an ongoing debate if this old practice is necessary now that we use HTTPS on every website.

Upvotes: 12

Lance Pioch
Lance Pioch

Reputation: 1167

Your domain is invalid. You need to look at config.session.domain and config.session.path.

Upvotes: 2

Related Questions