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.
Related
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
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.
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.
I have multiple xmlHttpRequest on my page, and I am attempting to call the abort() method on them all. Works great in FF. IE, on the other hand does not do a darn thing. The connections do not close, and I am unable to navigate to another page until the requests complete. What is this? Why doesn't IE close the connections when abort() is called?
I've almost never gotten abort to work in IE. I'm tired and can't remember why - something about not being able to abort until you're in readyState 4 (or maybe that it changed to readyState 4 when it aborts?). Either way, Ajaxian has a work around in the depths of its' archives:
http://ajaxian.com/archives/reusing-xmlhttprequest-without-abort
Parallel-Ajax requests vs Apache-Session locking
Session data is usually stored after your script terminated, but as session data is locked to prevent concurrent writes only one script may operate on a session at any time.
When e.g. using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as possible.
So you can use sessions in ajax scripts with
session_start(); (maybe handled automatically) followed immediately (soon as possible) by session_write_close();
session_write_close(); will "end" the current session and store the session data.
But: session_id() will still deliver the correct (current) PHPSESSID so you're able to re obtain write access to the current session by simply doing session_start() again at any time you need it.
I use it this way in all my ajax scripts to implement session handling and allowing parallel request (with aborting) in all browsers
I'm using Zend Framework for PHP and handling sessions with the Zend_Session module. This is what I have in my Initializer (or bootstrap):
Zend_Session::start();
Zend_Session::rememberMe(864000);
864000 seconds should be good for 10 days, but I'm still being kicked out at about an hour (or maybe a little less). I've tested to see if this statement works at all by setting it to 10 seconds, and indeed I am kicked out at the appropriate time, but when I set it to a very high value, it doesn't work! I went through some of the documentation here:
http://framework.zend.com/manual/en/zend.session.html
Another method I saw was to use the following:
$authSession = new Zend_Session_Namespace('Zend_Auth');
$authSession->setExpirationSeconds(3600);
Now, I have different namespaces. Does this mean I have to set this for all of them if I want to keep them from expiring? I haven't tested this method of setting the expiration, but I really wanted to see what the gurus on here had to say about what the correct way of approaching this problem is. Thanks a lot guys...
Also, does anyone know how I can make it so that the session never expires? I've tried setting the second to 0 and -1, but that throws an error.
I had the same problem and solved it by putting:
resources.session.save_path = APPLICATION_PATH "/../data/session/"
resources.session.gc_maxlifetime = 864000
resources.session.remember_me_seconds = 864000
in the application.ini (as suggested by tawfekov) and
protected function _initSessions() {
$this->bootstrap('session');
}
in the Bootstrap.php (this I typically forgot at first). You have to give the session directory the correct access rights (chmod 777). I described the issue here. Hopefully this will help the next person with the same issue.
Your client's computer clock, date, AND time zone need to be set correctly for session expirations to work. Otherwise the time conversions are off, and likely causing your cookie to expire the minute it hits the their browser.
Try calling remember me before starting the session:
Zend_Session::rememberMe(864000);
Zend_Session::start();
Otherwise I believe it will use the default of remember_me_seconds. See 49.4.4. rememberMe(integer $seconds)
Also, does anyone know how I can make
it so that the session never expires?
I've tried setting the second to 0 and
-1, but that throws an error.
I don't think that is possible. The session is controlled by whether the cookie exists on the users computer. Those cookies can be deleted, even by the users if they clear their cache. I think the best you can do is set it to a very large number. Say 12 months.
I guess you are using ZF 1.8 or above ,
so you can put in the config.ini file
resources.session.save_path = APPLICATION_PATH "/../data/session"
resources.session.remember_me_seconds = 864000
and these setting will automatically loaded
again only in ZF 1.8 or above if not you had to load these config manually
i hope it helps you :)
Are there other PHP applications running on the server?
Assuming you're using the standard, file-based, session handler, PHP will store all sessions in the same place (typically /tmp).
If you have some other script on the server using the default session_gc_maxlifetime settings, it may be eating your session files.
The easiest fix to try is to configure PHP to store session files for this application someplace special -- that way other apps running on the server will never accidently "clean up" session data from this app.
Try creating a directory like /tmp/myAppPhpSessions (or whatever), and adding:
ini_set('session.save_path','/tmp/myAppPhpSessions');
ini_set('session.gc_maxlifetime', 864000);
at the very top of your bootstrap file.
Make sure session.auto_start is off in php.ini