68

I'm having an interesting issue with Laravel 5.

After logging in a user, the logged in status is not persisted across pages. Clearly it has something to do with Session::.

The way I'm logging in a user is pretty straight-forward:

if (Auth::attempt(['email' => $data['email'], 'password' => $data['password']],
    isset($data['remember_me']) ? TRUE : FALSE))
{
    return redirect()->intended('/');
}

A simple print_r(Session::all()); gives me the following if the user is NOT logged in:

Array
(
    [_token] => wV8o75lZnCZ0f6CMMQgdBBM2AxSYjtWisAXx6TgZ
    [flash] => Array
        (
            [old] => Array
                (
                )

            [new] => Array
                (
                )

        )

    [_previous] => Array
        (
            [url] => http://localhost/public
        )

)

After the user is logged in an redirected to / the array looks like this:

Array
(
    [_token] => wV8o75lZnCZ0f6CMMQgdBBM2AxSYjtWisAXx6TgZ
    [flash] => Array
        (
            [old] => Array
                (
                )

            [new] => Array
                (
                )

        )

    [_previous] => Array
        (
            [url] => http://localhost/public/
        )

    [login_82e5d2c56bdd0811318f0cf078b78bfc] => 2
)

However, after any action that will lead to a page refresh or a redirect, the session status is lost.

My config/session.php file looks like so:

<?php

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,

];

The locally stored file for the session can be written and read.

I've tried using database drive instead of file. Same thing happens the [login_xx] => 2 key/value is lost and I'm logged out.

Since the Session:: is not completely reset I'm suspecting that I'm not logging in the user properly or simply doing something that I shouldn't be doing somewhere.

Andrei
  • 3,434
  • 5
  • 21
  • 44
  • And `Auth::check()` after the redirect returns `false`? – Bogdan Jun 11 '15 at 00:49
  • Sorry about the late reply, after the initial redirect to `/` it returns true. After any action, it will return `false`, yes. – Andrei Jun 11 '15 at 06:20
  • Are you using any sort of encryption with your password? Right now it looks like you are attempting to log the user in with a plain text password. Laravel ships with `bcrypt`, and if you are using the Registrar right out of the box, the create method uses `bcrypt`. Try `Auth::attempt(['email' => $data['email'], 'password' => bcrypt($data['password'])` – brokekidweb Jun 12 '15 at 12:33
  • 1
    The password is encrypted by default when using `Auth::` it's actually no recommended to do what you suggested. – Andrei Jun 13 '15 at 11:34
  • where is `$data['remember_me']` coming from? – Félix Adriyel Gagnon-Grenier Jun 13 '15 at 14:32
  • 1
    From the view, it's just for the remember me token. I've tried without it too. Same thing. – Andrei Jun 13 '15 at 14:38
  • @Andrew just a stupid question: is your browser saving cookies? And are you able to login at all? – sitilge Jun 13 '15 at 19:35
  • @sitilge Yes, it does as far as I can tell. Checked with both php and js. All seems to be in working order...you know, except for the sessions persisting "small" issue. – Andrei Jun 13 '15 at 21:04
  • @sitilge And yes, I am able to login, but as I said, as soon as a page refresh happens or any other redirect for that matter, the session gets reset. – Andrei Jun 14 '15 at 01:22
  • Looks alot like just session failure to me. Are you sure the session directory is writeable by the web server? Have you tried other session drivers? You should ideally use Redis or Memcached. – Laurence Jun 14 '15 at 11:34
  • @TheShiftExchange I am absolutely sure the directory is write-able . I've checked it a dozen times so far. I'll try switching Monday to another computer. Maybe there's something wrong with my home machine. – Andrei Jun 14 '15 at 12:11
  • Have you switched to say the database/redis/memcached driver so you can rule out the filesystem completely? Not as a permanent solution as you say you'd like to stick with the file driver but it'll help discern certain things if it works/fails with other drivers – Ben Swinburne Jun 16 '15 at 09:46
  • @BenSwinburne I have not. I'll try to get around doing that today. I was stupidly busy lately. I will update my question as soon as I get a chance. – Andrei Jun 16 '15 at 09:48
  • @BenSwinburne Just tried it a minute ago. Same thing. The data is written in the database, but as soon as refresh/redirect happens the `[login_82e5d2c56bdd0811318f0cf078b78bfc] => 2` key/value is lost. At this point I can't even begin to guess what's wrong anymore. – Andrei Jun 16 '15 at 13:36
  • Have you perhaps got some middleware or filters which is causing a problem? Perhaps middleware `guest`? Is this 5.0.x or 5.1? If it's 5.1 did you upgrade from 5 or fresh install? – Ben Swinburne Jun 16 '15 at 13:57
  • @BenSwinburne No middleware, I wasn't using the out-of-the box middle ware, but I've specifically removed every middleware that came with the default installation just now, as in deleted the files, no difference.. It's 5.1.2(LTS), using `php artisan --version` to determine that. I have not upgraded, it's fresh out of the box. I've tried it on my work machine too, which is running Ubuntu, same thing. The `md5` hash is lost. – Andrei Jun 16 '15 at 14:02
  • Interesting. What's the session lifetime set to? `dd(config('session.lifetime'))`. Do the same with `session.driver` and make sure it's not defaulting to `array` somehow. – Ben Swinburne Jun 16 '15 at 14:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80684/discussion-between-ben-swinburne-and-andrew). – Ben Swinburne Jun 16 '15 at 15:03
  • @BenSwinburne `session.lifetime` = 120, `session.driver` = database. – Andrei Jun 16 '15 at 15:03
  • Hey if you are using database then you should check if the session info are stored on database or not. – Dipen Jun 17 '15 at 09:00
  • create a simple app with session if you can access session variable across pages then u may have missed some thing while implementing Auth check configuration / model classes and how session are set if user is successfully logged in. – Dipen Jun 17 '15 at 09:18
  • 3
    Can you please provide the HTTP headers in the response right after logging in? It's just a guess but maybe the cookie is set on some different domain. Check that the Set-Cookie domain is the same as the domain you access the application on. – s3v3n Jun 17 '15 at 09:46
  • Session files are stored in "Storage/framework/sessions". Maybe the problem is due to insufficient permission for the storage folder. – SachinSunny Jul 01 '15 at 06:17
  • I answered, if that didn't answer your question, please take the time to comment to my answer and explain how it wasn't. I'd appreciate the feedback; answering takes time away from other things. – Rob_vH Jul 10 '15 at 20:17
  • this happens in the production environment or the development environment? – Ammadu Jul 22 '15 at 12:49

21 Answers21

13

I faced similar issue, I simply called:

Session::save();

after any add/update/delete to Session storage. So it looked like:

$id = Input::get('id');
Session::forget('cart.' .$id);
Session::save();
Kalpesh Panchal
  • 965
  • 9
  • 20
  • 1
    This fixed the problem for me under laravel 5.3. Before adding `save`, no custom session data is saved to the file, after that everything's just fine. However I just don't understand: `Session::save` is totally missed out in [the doc](https://www.laravel.com/docs/5.3/session), without which the session is just unusable, why would the laravel team do this? – JJPandari Dec 28 '16 at 06:52
  • 1
    This FINALLY solved my issue. Session::save(); Is required. – Rohan Jetha Oct 31 '17 at 07:41
  • 1
    @RohanJetha Session::save() is only required when your script stop by exit or die function. Then you have to add this function after session define and destroy function. – Bhavin Thummar Sep 10 '18 at 12:50
  • 1
    @BhavinThummar thank you! I had a `dd()` after an `Auth::attempt()`. The attempt was successful, but the login was never persisted. Removed the dd and it persisted fine! – Phil Cross Jul 03 '19 at 23:33
  • @PhilCross , If your problem is solved by understanding, then it is too good. – Bhavin Thummar Jul 04 '19 at 05:08
12

I had the same issue. Once I removed the various combinations of dd() and print_r() I was using to dump responses for testing purposes and allowed the method to complete and fully render the view, the issue went away and sessions persisted.

supernifty
  • 4,171
  • 2
  • 32
  • 24
  • This worked for me (using Laravel 5.1). However, using the return parameter on `print_r()` allows the persistence of the session: `print_r($request->session(), true);` – Shane Sep 21 '15 at 04:30
  • 1
    This is correct. The sessions are saved at the end of the request lifecycle. So, interrupting the execution will prevent the session from being saved. Use dump() instead of dd() or manually trigger the save with Session::save() – Arian Acosta Jun 25 '17 at 19:59
  • 1
    @spedly.wasted 4 to 5 hours to fix this .but your answer saved me finally – Vision Coderz Jan 15 '18 at 19:15
7

I solved changing

'cookie' => 'laravel_session',

to

'cookie' => 'myapp_session',

according to laravel the name of the cookie affects every driver

  • I also faced a similar problem and resolved the above answer. check here https://stackoverflow.com/questions/46216511/session-is-expiring-automatically-in-laravel-5-2 – prudhvi259 Sep 15 '17 at 04:23
2

I'm not familiar with Laravel, but on CodeIgniter I save user session in CI's Session Class and Laravel has one too.

I suggest to use the build-in session which is more persistent than default $_SESSION - probably it saves user data in database and on each page refresh/change the session is populated again from DB.

When user authenticates, just save its session data like this:

Session::put('userData', 'value');

...where value could be just a boolean value or an entire object that holds user specific data.

On each page load, get user data from session:

$user = Session::get('userData');

if($user->id) echo 'user is logged-in'; //or if($user) - depends on what you store in 'userData' key
else echo 'guest only privilegies';

EDIT: I see that you use the Auth Class. My answer is mostly for manual login of the user and it works.
I think that the Auth Class should be doing this by default, but probably you're missing some configuration or there's a bug.

Here's a possible solution (Laravel 4, but it worths a try): http://laravel.io/forum/11-11-2014-authcheck-always-returning-false

Update:

As of this you should try to change the driver value from

'driver' => env('SESSION_DRIVER', 'file')

to

'driver' => 'file'

...also on Laravel's docs you can see that the driver has to be defined like that.

Community
  • 1
  • 1
Tanase Butcaru
  • 962
  • 1
  • 10
  • 23
  • That link is purple unfortunately :( . I've google'd everything I could think of for the past 2 days. – Andrei Jun 13 '15 at 12:43
  • Just do some ``put`` and ``get`` within Session Class and see if the data is still there after page refresh/change. If data is not lost, then it's a problem with Auth Class or something else you're doing in your app. – Tanase Butcaru Jun 13 '15 at 12:45
  • Did you try all possible Session Drivers? I would go with "database". – Tanase Butcaru Jun 13 '15 at 12:48
  • I did try indeed try with `put` and the values are stored properly, I can in fact retrieve them with no issues. I'll give the database drive a shot too, although I'd rather remain with the file. But in the position I'm at I can't complain. – Andrei Jun 13 '15 at 13:12
  • i've updated my answer with a possible solution. i think that might be it :) – Tanase Butcaru Jun 14 '15 at 22:27
  • 2
    @TanaseButcaru your latest update is incorrect (or unfavourable, let's say. It would technically work) and the wrong way to define the driver. Laravel 5 uses DotEnv to configure settings. The `env()` function will look at a file entitled `.env` for a definition of `SESSION_DRIVER` and use that. In the absence of that definition it will fall back to the second parameter which is in this case `file` – Ben Swinburne Jun 15 '15 at 10:45
  • 1
    Actually the last solution worked for me. Every reload/request my session file was being changed. Replacing `"'driver' => env('SESSION_DRIVER', '')"` for `"'driver'=> ''"` worked like a charm. – scarface13 Feb 25 '16 at 17:13
1

First, make sure you don't have some sort of a before filter, middleware, or route group that is causing them to be logged out. At least temporarily, search for any Auth::logout() and comment it out. I have seen this be the problem more than once.

Second, you look like you're doing this call correctly. The third parameter is $login : bool and it defaults to true. This is not your problem, but please change your TRUE and FALSE to true and false to meet with PSR-1/2 standards.

I would have advised that you try another driver, but you have done that and have the same result. This leads me to think that you have some sort of earlier code that is misdirecting to a logout().

Rob_vH
  • 760
  • 8
  • 11
1

You need to make sure of 2 things if you are using default laravel's file session which you can check if you are using in session.php file.

  1. The session directory ie storage/framework/session/ is writable.
  2. The routes for logging in maybe (/login) and for checking authentication (maybe /dashboard) are all within the group web

ie.

Route::group(['middleware' => ['web']], function () {
   Route::get('/home/login', ['as' => 'login', 'uses' => 'HomeController@getLogin']);
Route::post('/home/login', ['as' => 'login', 'uses' => 'HomeController@postLogin']);
   Route::get('/home/dashboard', ['as' => 'home', 'uses' => 'HomeController@getDashboard']);
}

This worked for me in Laravel 5.

Y M
  • 2,105
  • 1
  • 22
  • 44
1

I had this problem to and i solve this way. After Auth::attemp or Auth::login() dont use echo, var_dump or dd() i dont know why but those prevent to keep the session in the browser.

And now is working

                public function testLogin(Request $request, $id){

                    $user = Account::find($id);
                    Auth::login($user);

                }
Rolly
  • 3,205
  • 3
  • 26
  • 35
1

Don't forget to save like session()->save() or Session::save()

1

I have faced the same issues after the user logged in the session is not persistent. So i found the solution for this. just change one line in config/session.php file

Change in this code

'cookie' => env( 'SESSION_COOKIE', Str::slug(env('APP_NAME', 'laravel'), '_').'_session' )

To:

'cookie' => env(
    'local_cookies',
    Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),

then clear the caches. it will fix the issue :)

Faizan Ali
  • 11
  • 1
0

correctedHum... Ensure your machine is setted with good date and hour, and equally the other machines on the network who working with.

For exemple in Debian system:

In the command prompt, hit date (you will see the date), if it's not correct follow these instructions:

  1. apt-get install ntp
  2. service ntp start
  3. date (normally the date and hour are corrected)
ShuifuraX
  • 19
  • 3
0

Use "cookie" driver instead of "file" of session.php (config\session.php\driver). I had a problem with login using "Auth::loginUsingId()" api instead of "Auth::attempt()" api, it destroyed the session for another request.

namal
  • 1,164
  • 1
  • 10
  • 15
0

Make sure that the target route also uses the middleware StartSession. In my "fresh" installation of Laravel 5.2 the "web" middleware group uses it, but the root path (/), which also happens to be the default $redirectTo after login, was outside of it. Huge loss of time.

iipavlov
  • 1
  • 2
0

I had a similar problem and I have fixed it by changing the Session Driver from SESSION_DRIVER=database to SESSION_DRIVER=file

Juan Girini
  • 1,150
  • 2
  • 16
  • 31
0

In my case I had to change the domain setting in the app/config/sessions.php file. I had a different domain written there instead of the one that I was using and naturally it didn't work. Though I don't understand why the framework went ahead and created the session files each time I was reloading the page.

0

I had the same issue, but it has been fixed now.

It's because of the conflict between sessions in your machine and in your localhost domain. To solve the problem:

First of all check your config/session.php file and check this:

'domain' => null,

after that clear your cookies:

on Firefox, right click -> view page info -> Security -> View Cookies -> Remove all

Kamran
  • 11
  • 1
  • 4
0

i had the same problem in laravel 5.4, the solution for me was:

In the file /app/Http/Kernel.php, was commented middleware AuthenticateSession by default.

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        //\Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

Only uncommented this line and the session work fine in all routes

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];
rolodef
  • 115
  • 1
  • 3
0

If you are using loginUsingId() method you should set 'remember' flag to true.

So, instead of doing:

loginUsingId(1);

You should do

loginUsingId(1, true);

See docs

Abhishek
  • 3,900
  • 21
  • 42
0

You might wanna check public/index.php, see if there are codes before the Laravel codes. After I remove those codes, I can login just fine.

<?php
    echo 'hello';
?>

<?php

/**
 * Laravel - A PHP Framework For Web Artisans
 *
 * @package  Laravel
 * @author   Taylor Otwell <taylor@laravel.com>
 */

I seems, someone "messed" with my sites, and index.php is the main target for malicious codes

Irfandi D. Vendy
  • 894
  • 12
  • 20
0

Just add session start and authenticate middleware to global middleware in kernel.php file

Yaser Darzi
  • 1,480
  • 12
  • 24
0

just check then cookie allow false

'secure' => env('SESSION_SECURE_COOKIE', false)

In my case I put it as true insted of true, then I changed its into false

Kaushik shrimali
  • 1,178
  • 8
  • 15
0

I am faced this problem when dealing with the oracle database, and by searching and debugging it is solving by change the protected $primaryKey = "name in lowercase" public $incrementing = false;