CodeIgniter - execute function when session expires - codeigniter

I'd like to update my own database when session expires. To do this I modified CodeIgniter's Session file and wrote my own code in sess_destroy(). Everytime the user logouts, sess_destroy() is called. It works correctly as my database gets updated. My problem though is that my database doesn't update when session expires. To test it, I set the sess_expiration in the config.php file to 20 seconds so I wouldn't have to wait long for it to expire. After it does expire, login details that are supposed to be displayed are gone, meaning the session is gone. My database, however, was not updated at all. I've tried inputting code in unset_userdata() and sess_gc() but database still doesn't update.
Suggestions are welcome. Thank you

The only way would be to call some sort of cron job to regularly scan the database of sessions for expired sessions and purge them or log them etc. Nothing is going to trigger that automatically.

Related

Laravel 5.1 randomly dropping session data

I have a strange issue with a Laravel 5.1 application.
Intermittently, it’s dropping session data. I’m detected this by writing some middleware that writes the contents of the session for that request to the log file. Although the session ID (Session::getId()) doesn’t change, the value of _token in the session data retrieved with Session::all() does.
As I say, this happens intermittently. I can refresh the same URL multiple times, and then randomly on one refresh the session data’s gone, and the _token value’s different from the previous requests.
What would cause this? I’ve also noticed the flash object isn’t in the “dropped” session data.
Below is a snippet of the log. You can see the content of the session_data key randomly changes “shape” in the last two lines, but the session ID remains constant.
Also, not sure if it’s pertinent, but I have DebugBar enabled.
UPDATE: Through debugging, I’ve found that on some page loads the session is completely empty, as in, no _token (hence a new one getting generated). Nothing.
If you're using the file driver, you could run into race conditions on concurrent requests. The file then gets truncated, Laravel can't read it, so it refreshes the session. Race conditions can also lead to a symptom where something you're putting to the session just doesn't get put. This tends to be random, so it's very hard to debug. According to the Laravel team, this is a known limitation of the file driver and it does not appear to be getting fixed, so I would suggest using a different driver. This would fix your issue of random session refreshes, but it still introduces a possibility of making a change to the session that doesn't get added. As far as I know, at this point with Laravel 5.1, you'll have to manage that yourself.
Somehow your session data is too long and being truncated. If you're using the database driver (haven't tested other drivers), and you try to save session data that's longer than the field length, then subsequent requests won't be able to pull from this session, and you'll wind up with a new session. If this issue is happening randomly with very short session data, then it's probably the cause listed above.
If you use Linux, Try using Redis (http://redis.io) as session / cache manager in laravel. I had some issues in the past with text / cookies and laravel in some servers. When I instaled Redis I had no problems anymore.
More info: https://laravel.com/docs/5.1/redis
Using a different driver like memcached did not solve the problem for me.
Here is a package that implements session locking which works and very simple to incorporate in your projects.
https://github.com/rairlie/laravel-locking-session

Laravel 4.2 -- New database session "exists", not saving + jasny/sso

Long story short: I have hacked jasny/sso to work with Laravel. It works extremely well except when the primary/root session has expired.
I have the primary/root authentication set to "remember", so it can reauthenticate from the cookie when the session has expired.
When the 'attach' action happens on the SSO server and the primary/root session has already expired, I am running Auth::check() to bring the session back to life so that it can be attached properly.
All of my debugging indicates that everything is working exactly as I need it to except for this one little detail:
The new session generated by the 'attach' action is never written to the database because the DatabaseSessionHandler thinks it already exists. It is running an UPDATE instead of an INSERT.
As a result, my SSO client session attaches to a non-existent SSO server session.
For the life of me, I can not figure out why it thinks this new session already exists nor how to get it to correctly insert into the database.
Can anyone tell me why a new Laravel 4.2 session would be detected as "exists" and run UPDATE instead of INSERT on save()?
EXTRA DEBUGGING ATTEMPTS --
Attempt #1: I have tracked this to a false attachment to an expired session that hasn't been garbage collected yet. What I don't understand is how this session is being loaded while a different session ID is being presented. If this were the result of the migrate() or regenerate() methods, "exists" would be set to false, and it would save correctly. Somehow, it seems that the session ID is being updated without resetting "exists".
Attempt #2: The answer was staring me in the face the whole time. I kind of understand the downvote now. (see my answer below)
I was dramatically over-thinking this as I tried to uncover the mechanism behind the behavior instead of testing what looked like an easy solution:
If I call Session::setExists(false) prior to Session::save(), it will insert the new session correctly.
EDIT: If wrapped in an if-statement for Auth::viaRemember(), I can check if the auth happened via session or cookie/remember. If true, then I want to set "exists" to false.

Need to Update database when session expires or browser closed Codeigniter

I have table of 'users' having 'is_login' column. When a user logged in. 'is_login changes to 1' AND when log out 'is_login changes to 0'.
But if user closes browser, that 'is_login' column stays 1.
I need a method to update database, when session expires by closing browser.
I have tried this but not done:
How to exec a function when codeigniter session expires
I am open to other suggestions as well.
You would need to use some javascript/jQuery to catch when the browser is closed down and make an AJAX call to a script at your application that can set the logged in flag to 0. Using jQuery
$( window ).unload(function() {
$.post('location/of/your/script.php',{'identifier':'identifier_val'});
});
Then in script.php pick up whatever you post and act on it.
This is pretty unreliable in my experience and not a great experience for the user as this will fire if they reload the page. The other (equally nasty) way would be to use the heartbeat method. Essentially your jQuery needs to ping your server every minute. Then you would run a CRON job to check any user records that did not get a ping from the jQuery for more than 2 mins (or whatever you think is correct) and set those users to logged out.
Otherwise you need to open a socket connection with your server which is the proper way to do it.

Login & Session not working on localhost using codeigniter & Ion_Auth

I have a live site which works fine and can be logged into no problems. I have a local copy of that site but for some reason the session isn't working. If i login, i can tell that the login has worked as it tries to redirect to the success page and i can see that a new session gets started.
But, the system doesn't recognise me as being logged in.
I've changed the cookie_domain config variable, changed session_ip and session_user_agent matching variables but nothing seems to work.
Also, i increased the size of the fields that hold session/userdata data in the db to longtext to make sure nothing was being chopped off.
Is there anything i've missed, anything that i've forgotten?
Ahhh, my bad. I didn't realise i had a dev only config in there that needed to have it's cookie domain changed. Whoops!!

Keep Accounts Logged In

We have an internal control panel that all employees in the office are logged into all day, including customer service. I'd like for it to be setup so that it keeps you logged in for 1 hour before your session expires. How can I change this in the PHP.ini? I made a change before I understood would keep the session open until the browser window was closed but it didn't stick.
There are two different values you can set:
session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage' and potentially cleaned up.
and session.cookie_lifetime which is how long the cookie will last.
http://www.php.net/manual/en/session.configuration.php
both values can be set in the php.ini file, but might get overriden in .htaccess files or in your scripts using ini_set.
You can also do this client-side using JavaScript. Use an AJAX call to periodically 'check-in' with the server, keeping the PHP session alive. You can also monitor if the user is doing anything on the current page, show them a '2 minute warning' message, or even redirect them to a 'session terminated' page when the 1 hour inactivity period is reached. You could even use this to 'force' a user to be signed out.
This isn't as secure as doing it purely in PHP, but does give you more flexibility to build cool features.
The most secure place to implement this would be in your application. You can store the session update time in $_SESSION on each page load. Before you update it, you check if it has exceeded the 60 minute limit, in which case you can use session_destroy() to terminate the session, followed by a redirect to the login page (or similar).
I don't think this can be done from the php.ini file. I think you either want to store the login time on the server and compare that with the current time and delete if 60mins have passed, or alternatively, use cookies -- these can have an explicit lifespan. See this for more information on cookies.

Resources