9

Here's config/session.php:

return [
    'driver' => 'file',
    'files' => storage_path().'/framework/sessions',
];

My storage/framework/sessions have 755 permissions.

When I put these 2 line in my controller

Session::set('aa', 'bb');
dd(Session::get('aa'));

I receive expected "bb" output. But if I comment first line:

// Session::set('aa', 'bb');
dd(Session::get('aa'));

and refresh page, I still expecting "bb" but getting null.

Also, storage/framework/sessions is empty.

What should I do to make Session working?

Limon Monte
  • 52,539
  • 45
  • 182
  • 213
  • 1
    Who's the owner of `storage/framework/sessions`? `755` means only the owner can write to the directory. So for those permissions to work the owner most commonly should be the webserver user, which in general is something like `www-data`, `apache`, etc, depending on what Linux distribution and HTTP server you're using. – Bogdan Mar 30 '15 at 13:21
  • Try setting it to `775` instead – lukasgeiter Mar 30 '15 at 13:45
  • @Bogdan I think it's not about permissions, set to ``777`` and session still does not work. – Limon Monte Mar 30 '15 at 13:55
  • just tired ``cookie`` and ``database`` drivers, the same :/ this is weird. – Limon Monte Mar 30 '15 at 14:06
  • just tried on another project without vagrant - the same! Can anybody confirm getting ``"bb"`` after commenting ``Session::set()`` from my simple example? – Limon Monte Mar 30 '15 at 14:10
  • 1
    I think it's because Laravel has a custom session handler, and doing `dd()` interrupts the request lifecycle before the code responsible for actually storing the session data in the file can be executed. Try using `var_dump()` instead of `dd()`. – Bogdan Mar 30 '15 at 14:12
  • @Bogdan you're the lifesaver! please separate this answer to answer so I can accept it for further readers. – Limon Monte Mar 30 '15 at 14:15

3 Answers3

19

Laravel 5 handles sessions via a middleware class called StartSession. More importantly, this middleware is a TerminableMiddleware and the code that actually saves the data (in your case to the session file) is located in the terminate method, which is run at the end of the request lifecycle:

public function terminate($request, $response)
{
    if ($this->sessionHandled && $this->sessionConfigured() && ! $this->usingCookieSessions())
    {
        $this->manager->driver()->save();
    }
}

When calling dd(Session::get('aa')); the request is being interrupted before the terminate method of the middleware can be called.

Funnily enough, the Laravel Middleware Documentation actually explains Terminable Middleware logic by giving the Laravel StartSession middleware as an example:

For example, the "session" middleware included with Laravel writes the session data to storage after the response has been sent to the browser.

That being said, try using var_dump() instead of using dd().

Bogdan
  • 43,166
  • 12
  • 128
  • 129
  • 1
    @limonte Your issue was interesting enough that I decided to do a little digging to understand the exact cause. I've updated the answer with a more detailed explanation of what is actually happening. – Bogdan Mar 30 '15 at 15:02
  • 1
    Thank you for your explanation. Is there a way of saving a session content before request ends ? I know we can manually call Session::save() but this does not seems to do the trick. I would really need to be able to do so! – thiout_p Mar 21 '16 at 12:30
  • @thiout_p What session driver are you using? If you're using any driver besides `cookie`, using `Session::save()` will work, as the session is written immediately. However, if you're using the `cookie` driver, then the session cannot persist since the cookie is stored on the client and sent with the application response, and that response is not sent anymore because of `dd`. – Bogdan Mar 21 '16 at 18:49
  • Thank you for your answer. I had a typo in the .env file for the **SESSION_DRIVER** record's key that was missing an R I'm working on something else so I couldn't check if this was related. (but I guess it would!) anyway thank you for the explanations! :) – thiout_p Mar 22 '16 at 11:03
  • The same happens if you use dump(). It messes up the session! – Bartosz May 20 '17 at 23:10
3

With laravel 5.*, you must change the kernel file like bellow:

  'api' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Session\Middleware\StartSession::class,
            'throttle:60,1',
            'bindings',
        ],

then go to storage/framework/session folder and change the permission to 755 if it has another amount, then delete all files in your storage/framework/session path, use your code again to put something in a session, watch the storage/framework/session folder.

If your session work you can see the weird long file that belong to session right now, and you are done!

If your problem is not yet solved, go to config/session and change:

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

to another predefined amount like:

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

or even

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

and finally if you have an empty folder of storage/framework/session, you still have a problem for sure !!!

enter image description here

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
1

if you're use api route , you might have this problem with your session and most of the time sessions return null , try to use web route for this