Hello
Does anyone have any experience with using Varnish cache (https://www.varnish-cache.org/) with Fuel? I'm struggling because the Session cookie (fuelcid) seems to be set with every session which is invalidating the cache.
I've set auto initialise to false but whenever I call Session::get or ::get_flash (for example to see if a user is logged in), it creates a session. I only want the fuelcid session to exist if a user is logged in.
Any ideas anyone?
Thanks
Mike
For one thing it might be better to devide your website up into pieces that are AJAX loaded and only use the Session class on those sub-requests that require processing. (I also think you can probably configure Varnish to ignore those requests)
But to solve this you could check if the fuelcid cookie already exists and only execute the code using sessions when it does.
(I also asked WanWizard if the Session class itself shouldn't work like that)
Hi Jelmer
Thanks for the reply.
I thought it might be a case of checking it exists before calling anything on Session.
I'll second a more lazy session class, thanks for making it an issue.
Hi WanWizard
I think my problem was if I try and get a session, it sets a session. In my case I only want a session if the person is logged in - if I try and get a session to see if the person is logged in (which happens on every page) then a session is set regardless.
I've fixed it in a slightly hackish way by extending the Session class in the app and overwriting the get and get_flash function to check if the session has been set yet before calling the parent::get.
Can you explain what exactly the problem with Varnish is, which used in front of a FuelPHP site?
It is a piece of cake to exclude the session cookie in the Varnish configuration. If that doesn't give the desired effect, and you are in the same situation as Mike:
* disable autoloading of the session in the session.php config by setting auto_initialize to false
* in your app bootstrap, after you initialized Fuel, check if the session cookie exists using Input::cookie()
* if it exists, start the session by calling Session::forge()
* and check login state with Auth::check(). If not logged in (or login expired), call Session::destroy()
* in your login controller, call Session::create() after a successful login
* in your logout controller, call Session::destroy() after logout
The only issue at the moment is that destroy() currently only destroys the data, but not the session itself, I'm working on a rewrite to fix that.
I'm putting Varnish in front of my website (locally first). All pages are readable without an account and one can login to interact. I'm looking to cache my unlogged pages with Varnish. Since it's creating a fuel*id cookie, it's not cached.
I first thought I could ignore it in Varnish but how would I make Varnish know when one has logged in ? Then I went into looking how I can avoid this default session, this is how I came up here.
I managed to do it your way and indeed it keeps the fuel*id cookie with a "deleted" value in the write event of Session.
The only thing you can do is to disable default Session class loading.
Then check manually in your base controller if the session cookie exist, and if so, load the Session class and call Auth::check() to set the login status. If it returns false (login expired), delete the session cookie manually using the Cookie class.
In your login controller method, Start the session if the user posted the login form. If the login failed, destroy the session and delete the session cookie manually before redisplaying the form.
In your logout controller, destroy the session after a valid logout, and again, delete the session cookie manually.
This way you should only have a session cookie if there is a used logged in.
I got it working in a way I only have a session cookie when the user is logged in, thanks for you help.
Somehow, my use of flash sessions doesn't work anymore (I guess since session is destroyed in my base controller). I though you might have an idea about it ?
The downside of this is obviously that you can't use sessions for public pages, and that includes flash variables. So if you use those to pass data from page to page, you have to come up with an alternative solution.
I've setup another session engine with a low expiration time
I've extended \Fuel\Core\Session class and made use of this session engine when calling a [get|set|keep|delete]_flash method.
In my after method, I destroy the session and delete the cookie unless get_flash returns anything.
It starts working well, except when I log out where I still have my session cookie with its deleted value. I'd say it's ok for user who have logged out but if there is any way they could get a HIT again from Varnish, that'd be perfect :)
Actually I've extended the Session class to be able to call Session::*_flash() and make it use the redis engine here without having to forge an instance everywhere I call a flash method.
I could have created another class but I thought it did the job this way.