On my index.php, I have a login form. The form has a method of POST and its action is sent to a authentication file i.e action="authenticate.php". In this authentication file I check to make sure the user exists, I start a session, and then I redirect back to index.php.
Because I want the index.php content to change, for example, there will be no login form but the user account information, I also place a session_start() at the top of my index.php...
The problem occurs when a user visits my page for the first time. Because I placed a session_start() at the beginning of my index.php, if the user leaves and decides not to log in, then I'm stuck with an empty session file which takes up space on the server.
Is this bad practice? Is there another method that I should use? I hope this makes sense.
PHP cleans up sessions that are not in use anymore.
The usual configuration is to only run cleanups on a percentage of requests, and then to clean up session files that haven't been used in the last 30 minutes. Note that this leaves an opportunity for sessions to live longer on sites that rarely have any requests, so it is best practice to record the enforced logout time inside the session itself if there is a need to log the user out when being inactive after for example 15 minutes.
Also note that on a badly configured shared hosting you might gain access to other sites session files and vice versa, which might also affect cleanup of session files if other sites have a different, shorter timed configuration.
But all in all PHP takes care of the sessions itself pretty well.
Related
For my Joomla! 3.8+ extension I need to be able to find and delete (unlink) PHP session files (named 'sess_' + session id) which will be stored in the session_save_path, e.g. /tmp. I understand that it is PHP who is storing the session files, i.e. not Joomla! (Joomla! session handler set to 'PHP')
My question: Will a PHP session file that is created through the use of the Joomla! website ALWAYS be read/write accessible by my extension's PHP code which is part of the same Joomla! install?
Addition: I realised later, that I omitted the word 'always' in my question, which I have now added.
Addition: More in-depth explanation about what I am trying to achieve.
As I said I have a Joomla! site, where users can log into.
The issue applies ONLY when Joomla! is configured with Session Handler set to 'PHP' (instead of 'database'). When Session Handler is 'database', there is no problem.
In basic terms, I want to achieve the following (with Joomla! session handler set to 'PHP'):
1> A user opens browser A and logs into the website and Joomla!
records the related session ID plus user ID in a database.
2> The same user opens a different browser B (maybe at a different IP)
and wants to log into the same website.
3> Because user has already logged into the website through browser A,
he/she is not allowed to log in again and will be presented a
clickable link that will destroy all his other sessions, including the
one with browser A (we have recorded the session IDs of all the other
sessions).
A mere session_destroy() in step 3 is just partly doing the trick, because the destroyed session details reappears after a little while at the Joomla! backend and also in the Joomla! session table. Although this does not interfere with the Joomla! front-end, it is not clean and I want to avoid it, to make it fool proof.
By far the best solution is if I could delete the PHP session file (for example in dir /tmp and named 'sess_....'). I have tested this and it worked fine. However... it relies upon always having delete access to the PHP session file (using session_save_path() and unlink($session_file_path)) and this is the basis of the question that I posted.
I found out that the delete of the PHP session file is not always possible; it depends on the providor's PHP config. Since it is a commercial app that I am developing, the process must work on all configs, i.e. including those that do not allow delete access to the session file.
I will continue my search for a solution and will post it here when I found it.
What you want is often possible but it poses a security risk (just think: one user can read session files before knowing who they belong to, so also those of other users), and therefore security-conscious ISPs will endeavour to prevent this.
So even if you manage to do this, nothing assures you that your code isn't going to break should the ISP tighten its security in the future. This makes for some maintenance uneasiness.
A better solution would be to have a secondary table of invalidated session-ids.
Then you write a user plugin hooking the onUserAuthorization and onUserLogout events. You will need onAfterInitialise too.
This hook will check upon initialisation whether the current session ID has been invalidated; if it is, immediate logout is triggered. Otherwise, its timestamp is updated.
On user logout, the current session id is removed from the table and the session destroyed.
At a fresh login, a warning about other sessions being open is issued: if login succeeds, all other sessions for the same user will be marked as invalidated.
As a maintenance task, all entries with a timestamp older than maximum session lifetime may safely be expunged.
That depends on the server settings.
Find the user PHP is using: How to check what user php is running as?
Check the permissons of that user on the folder where the sessions are stored: Unix: How to check permissions of a specific directory?
Change the permissions when needed: https://serverfault.com/questions/105535/how-can-i-set-full-premissions-to-a-user-in-a-specified-dir
Thank you #Nigel and #AgeDeO
By trial and error, I found out that the answer is NO, not always.
By executing the code with a few commercial ISPs, I hit one ISP who did not allow me to delete the PHP session file while it was at its default location. The location was /var/lib/php5.
I am using cakephp 2 and recently changed my session handler to database.
Everything seems to be working fine, except when a user leaves the website without logging out the session is left active.
In my core.php file I have configured database session handler as follows:
Configure::write('Session', array(
'defaults' => 'database'
));
How do I configure cakephp database sessions to destroy the session when a user leaves the site without logging out?
TIA!
You can't. PHP runs on-demand and can't possibly know when a user stops browsing the site. You basically have 2 options:
Write a script to check your session store to find sessions that haven't been accessed in X seconds, and clear them out. Call this script with a cron job.
Check the session when the user comes back, and clear out any stale data. You'll still need to do some cleanup from time to time to get rid of session data from users that never come back.
Sessions are stored on the server, so if the browser is closed or the user goes to a different page, there is no obligation that it informs the server about this action.
Session are stored for a certain time in the server, and after some time of inactivity, it will be destroyed there automatically.
Check Sessions info in CakePHP cookbook for more details
There is a possible solution that will work in some cases but probably isn't a great solution:
<body onUnload="ajaxFunctionToDeleteSession();">
some random stuff goes here
</body>
So ajaxFunctionToDeleteSession would call via Ajax a url that would delete the session.
A few problems with this that I see:
Called anytime someone closes an open page of your site. Which means if someone opens up multiple windows of your site closes one, their entire session, including for the other open tabs is closed
There are probably cases in which someone goes to your site, does something accidentally closes the open window, reopens the site and things will look different because the session is gone.
But if you absolutely must delete a session when someone leaves the site, this may give a way to start approaching the problem.
I have a large number of pages, each of which use a common header/footer. My wish is to keep the header and footer standard regardless of which page the user is on.
To access administration functions, the user presses an administration link at the bottom of the header. I would like this administrative login link to change to a log-out link after the user is logged in.
If I use session_start() in the header, then every page is going to have a session. I was told (I'm not sure if this is true or not) that it is bad practice to always have a session open.
Making matters worse in this regard, many of my pages use sessions (specifically all the administrative ones), and if you try and call start_session() after a header is sent (which obviously happens because my common header is parsed prior to the page content script sections being run, then it is an error.
To this point, I had been calling start_session() before the require line for the header on pages that would need sessions - but if the header now starts the session then this becomes an error.
If I need to know when an administrator is logged in within the common header code, how do I handle my session creation? Am I looking at this wrong?
I was told that it is bad practice to always have a session open.
yes. start your sessions only if you really need them.
otherwise it will make your site unnecessary slow, forbid browser from caching your pages when possible and such.
although you can't serve registered users without sessions, all other requests to the site (especailly from search engine bots) require no session support and there is no reason to start it.
how do I handle my session creation?
thre is a very simple solution.
call session_start() only on 2 occasions:
when user actully logs in.
when your script recieved a session identifier (means there is an active session running)
So, just add session_start() call right after the code checking user's password and modify all other calls this way
if (isset($_REQUEST[session_name()])) session_start();
There's the simple way of looking at sessions. If the page a user is on requires sessions, use sessions. Even if the page a user is on does not require sessions, if that page is one that a user reaches after a session has started, and it is reasonable to assume that a user will go from that page to another page that requires sessions, maintain the session. Don't keep starting and stopping your sessions. Just, as a rule of thumb, don't start the sessions until you need them and end them when you can be very confident that a user will not be needing them again during their visit.
In general, you are reinventing the wheel. Not using a CMS for these tasks is a waste of time and effort. In specifics, ob_start() is your friend.
I was told (I'm not sure if this is true or not) that it is bad practice to always have a session open.
That is hugely false. StackOverflow, Google, Facebook, etc. would all cease to function without an always-on session.
I have secured pages that all check for a set session variable to determine logged in users, pretty standard stuff. Where I run into problems is when I submit form information to a backend page that will process that data and then redirect to a success/failure confirmation page. In that time the session gets lost, at least the session with the variable. The session is still around because I can manually navigate to a secured page after and it works. Just auto redirects from a backend page to a secured page or a link on one of the unsecured pages after a redirect from the backend will fail. It may or may not be related, but after visiting multiple secured pages or doing one of the operations that use the problematic backend pages, there are two session cookies on my computer from the domain-- one registered to domain.com and the other to www.domain.com. At the end of my wits about this, thanks.
I see two problems here, but they're related.
The first is that you seem to be bouncing between secured (https://) and un-secured (http://) pages. Cookies aren't supposed to be shared between those, so that's why your session appears to break (PHP sets a cookie with the session ID).
The other is closely related and that is sharing between domain.com and www.domain.com. Cookies can share in one direction, but not the other. Don't worry about which: just pick one hostname and stick with it. Then check that you're setting the session's cookie domain to the correct one.
You must call session_start() from your PHP page before you output anything, preferably at the start of the page.
If the session has been already created, it will resume it for that page.
http://php.net/manual/en/function.session-start.php
I need to use the same session in different subdomains.
First I put
php_value session.cookie_domain ".aaaa.com"
on .htaccess file and upload it to root path.
when I need to use sessions. I just call
session_start();
Sometimes it works but sometimes it doesn't.
I tested this and found that.
If I go to login page the first time, then login and go to subdomain page. It works!
If I go to subdomain page and click to login page and go back to subdomain page by javascript window.location = 'http://sub.aaaa.com'; it does not work!!
If I login on 2 web browser with the same account it does not work!!
Are there another way? Or how do I fix this problem. I want my website to use a single login.
Make sure you have session_start() on every page you are using sessions, including some that might not be visible to the user.
If you are using two web browsers the sessions are independent from each other, and this is by design.
To debug your #2 problem, use an HTTP monitor such as HTTPFox to view the headers coming to/from the server as you log in and surf around, make sure the cookie is being properly set with the correct domain and path restrictions.
Probm #3 - I'm not sure what you're getting at. Are you using two seperate browsers (say Firefox and Chrome?), or do you mean you're using two windows/tabs of the same browser? For the first, two different browsers will not share cookies, so you can't share a single session between them, without doing some hacks to manually transfer cookies between them.
As for two different tabs/windows of the same browser, such an implementation depends on your login logic. If the login script starts a new session unconditionally, then you second login attempt will get a completely seperate session from the first login, and most likely overwrite the first login's cookie as well.