Ineffable Posted April 25, 2010 Share Posted April 25, 2010 I've got a simple login system using PHP sessions, but just recently it seems that if you visit pages not in a certain directory (/login/) you will always be flagged as not logged in, even when you are. It seems that my session data is being lost when I change directories (say, to /login/user/). I don't think I've touched the code myself since the problem appeared, is there something my web host could have done to my PHP installation that would delete the session data, and is there a workaround? Inside each file that needs authorization, i load a loginfunctions.php file which calls session_start() and checks the login. Files which work in /login and i copy and paste into /login/user stop working, even though i update all the relevant paths and links. Quote Link to comment Share on other sites More sharing options...
cags Posted April 25, 2010 Share Posted April 25, 2010 This should only cause problems if the other folder is being accessed via a different sub-domain (or accessed via FRAMES or FRAME forwarding). Other than that it's difficult to say without having a live example to inspect the cookies on. Try using the web developer toolbar for FF as a simple way to easily view active cookies and check for the session cookie on the various pages. Take particular note of the domain they are active on. Quote Link to comment Share on other sites More sharing options...
Ineffable Posted April 25, 2010 Author Share Posted April 25, 2010 Okay, thanks for replying. I used Firebug to monitor the cookies and the PHPSESSID cookie shows up when I log in, as expected. The domain is my website's domain and the path is "/", which seems right. When I visit one of the pages I get an 'access denied' from, the cookie shows no change. Interestingly, even though the cookie is not changing, if I then go back and visit the page before where I've just been (in the main /login/ folder which works fine), it now says access denied. So it seems that the server is losing the session information when I visit one of the pages in a subfolder. I'm just getting more confused the more I look into this problem... Quote Link to comment Share on other sites More sharing options...
cags Posted April 25, 2010 Share Posted April 25, 2010 It sounds like your session data is getting corrupted/removed at some point on one of those pages. Perhaps you are accidentally assigning a value to a session variable rather than comparing it at some point in the script? Quote Link to comment Share on other sites More sharing options...
Ineffable Posted April 25, 2010 Author Share Posted April 25, 2010 That's a good idea actually, but I've checked and nothing. I'm fairly sure it's nothing to do with my code because the page loads just fine if it's moved up a directory and the links are updated to reflect that. The only thing that changes when it stops working is the file's location. On top of that, I changed nothing since the whole system was working perfectly, and suddenly all the pages in subfolders log me out of the system. The only thing I can think of is that my server provider has changed a setting in my installation. Quote Link to comment Share on other sites More sharing options...
cags Posted April 25, 2010 Share Posted April 25, 2010 Good point, if moving the file makes it work then it shouldn't be that it's the script at fault. I really can't think of a reason that a sub-folder would not be part of the session if your domain is '/'. Quote Link to comment Share on other sites More sharing options...
Ineffable Posted April 25, 2010 Author Share Posted April 25, 2010 Someone else suggested setting the cookie domain before session_start() in each page, but that didn't work. Didn't think it would, since it was already right. If it helps, my session settings in PHP Info are as follows (local value in /login/ followed by the master value): session.auto_start Off Off session.bug_compat_42 On On session.bug_compat_warn On On session.cache_expire 180 180 session.cache_limiter nocache nocache session.cookie_domain no value no value session.cookie_httponly Off Off session.cookie_lifetime 0 0 session.cookie_path / / session.cookie_secure Off Off session.entropy_file no value no value session.entropy_length 0 0 session.gc_divisor 100 100 session.gc_maxlifetime 14400 14400 session.gc_probability 1 1 session.hash_bits_per_character 4 4 session.hash_function 0 0 session.name PHPSESSID PHPSESSID session.referer_check no value no value session.save_handler files files session.save_path /tmp /tmp session.serialize_handler php php session.use_cookies On On session.use_only_cookies Off Off session.use_trans_sid 0 0 Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted April 25, 2010 Share Posted April 25, 2010 You probably have links/redirects that are switching between www. and no www. on the URL's and your need to setup the session.cookie_domain to match both versions of your domain or you need to force any non-www. request to redirect to the corresponding www. address. Quote Link to comment Share on other sites More sharing options...
Ineffable Posted April 25, 2010 Author Share Posted April 25, 2010 Aha. Yes, if i change the url on a page that works and add a www. on the front, it throws me out again. However, if I change the front of one of the urls that don't work, it still seems to throw me out. When I log in, there's no www., but none of the links on the main page point to a url with a www. on them (all the links are relative to site root), so I don't think it's changing. I've tried putting in ini_set('session.cookie_domain', '.mysite.co.uk'); but I'm not sure that's the right way of setting the cookie domain to match both versions. It doesn't work, either way. Thanks. Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted April 25, 2010 Share Posted April 25, 2010 For debugging, add the following immediately after the first opening <?php tag on the main pages involved in the problem (both where you log in and where you are being told access denied) - ini_set("display_startup_errors", "1"); ini_set("display_errors", "1"); error_reporting(E_ALL); And while your code might not have changed, seeing what method you are using in your code generally narrows down and suggests what could have been changed on the server that could cause the symptoms. Quote Link to comment Share on other sites More sharing options...
Ineffable Posted April 25, 2010 Author Share Posted April 25, 2010 Yeah, sorry, forgot I hadn't posted any code. Inside each file that needs authorisation, it loads a loginFunctions.php file which calls session_start() and checks the login. Files which work in /login and i copy and paste into /login/user stop working, even though i update all the relevant paths and links. In the actual pages that are giving me the error, this is the auth. code: require_once("../../../includes/loginFunctions.php"); $login = new login; $login->checkLogin(0); Inside loginFunctions.php is this: class login{ function checkLogin($requiredAccess){ session_start(); if($_SESSION['accesslevel'] < $requiredAccess || $_SESSION['logged_in'] != TRUE){ die("You don't have access to this area. If you should have access, please log in again. <a href='/login/'>Login</a>"); } if (isset($_SESSION['HTTP_USER_AGENT'])){ if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])){ session_destroy(); die("Bad session. Please log in again. <a href='/login/'>Login</a> "); } } else { $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); } if (!isset($_SESSION['initiated'])){ session_regenerate_id(); $_SESSION['initiated'] = true; } } } The $requiredAccess variable is the access level that you need to access this page, so if you have an accesslevel of 3 in the database you can view level 0, 1, 2 and 3 pages. This is specified when the function is called in the main page and is compared to the access level of the current user which is defined in $_SESSIONS when they log in. I'm getting the error 'You don't have access to this area etc." when i try to access these pages. If i try to print the $_SESSION variables, nothing shows; they appear to be empty. However, if I move the file to the /login/ folder (one level up) and update the links, they work perfectly and all the variables print out (logged in status, name, accesslevel, ID). When I add in the debugging code, nothing prints on the pages that work, but when I get the error message I also get: Notice: Undefined index: accesslevel in /home/randomta/includes/loginFunctions.php on line 13 ...which I'm assuming is it not finding the accesslevel variable in $_SESSIONS. Quote Link to comment Share on other sites More sharing options...
cags Posted April 25, 2010 Share Posted April 25, 2010 The error message is what you say, it is saying that there is no accesslevel variable in the $_SESSION array. If a user isn't logged in to your site when that function is called you will always get that error. You can prevent that from coming up by doing something more like... if( !isset($_SESSION['logged_in']) || $_SESSION['accesslevel'] < $requiredAccess){ die("You don't have access to this area. If you should have access, please log in again. <a href='/login/'>Login</a>"); } ...rather than... if($_SESSION['accesslevel'] < $requiredAccess || $_SESSION['logged_in'] != TRUE){ die("You don't have access to this area. If you should have access, please log in again. <a href='/login/'>Login</a>"); } Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted April 25, 2010 Share Posted April 25, 2010 That's only the code that is checking the session variables. What about the code that is setting them or the code somewhere on your page that could be clearing them. Because you did not get errors about the whole $_SESSION not existing or an Undefined index error for $_SESSION['logged_in'], that implies that your code is setting 'logged_in' but is not setting 'accesslevel'. Best guess is that the part of your log in code that gets data from the database is not working and is not telling you what it is doing when it does not work. You could also have some code that either relies on register_globals to set same name session/cookie/program variables and your web host finally turned register_globals off (8 years too late) or you have some same name session/cookie/program variables and your web host managed to turn register_globals on and your variables are getting overwritten. Frankly, you are asking us what your code is doing without seeing your code. The quickest solutions come in help forums when you present all the relevant information and code so that someone can directly see the big picture and/or duplicate the problem. Quote Link to comment Share on other sites More sharing options...
Ineffable Posted April 25, 2010 Author Share Posted April 25, 2010 The code on the login page: <?php if($_POST['email'] != NULL){ session_start(); require_once("../../includes/DbConnector.php"); $connector = new DbConnector(); $result = $connector->query("SELECT * FROM artists WHERE email='".$_POST['email']."'"); if($resultArray = $connector->fetchArray($result)){ $salt = $resultArray['salt']; $pass = $salt.$_POST['password']; $hashPass = md5($pass); if($hashPass == $resultArray['password']){ if (isset($_SESSION['HTTP_USER_AGENT'])){ if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])){ die("Bad session. Please log in again."); } } else { $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); } if (!isset($_SESSION['initiated'])){ session_regenerate_id(); $_SESSION['initiated'] = true; } $_SESSION['logged_in'] = TRUE; $_SESSION['accesslevel'] = $resultArray['accesslevel']; $_SESSION['name'] = $resultArray['name']; $_SESSION['artistID'] = $resultArray['ID']; header('Location: optionpanel.php'); } else { die("Password incorrect. Learn to type."); } } else { die("Email ".$_POST['email']." not found"); } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Login</title> </head> <body> <form method="post"> <label>Email:<input type="text" name="email" /></label> <label>Password:<input type="password" name="password" /></label> <input type="submit" value="Beam me up, Scotty" /> </form> </body> </html> DbConnector.php just contains a class that handles my database interaction. It's all in MySQL. The code on the option panel page (page that you get sent to when you log in, this is the backend of a site so it's just ways to edit or upload stuff): <?php ini_set("display_startup_errors", "1"); ini_set("display_errors", "1"); error_reporting(E_ALL); require_once("../../includes/loginFunctions.php"); require_once("../../includes/DbConnector.php"); $login = new login; $login->checkLogin(0); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Options</title> <link rel="stylesheet" href="../css/backend.css"> </head> <script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </script> <script type="text/javascript"> try { var pageTracker = _gat._getTracker("UA-9571231-1"); pageTracker._trackPageview(); } catch(err) {} </script> <body onLoad=”javascript:pageTracker._setVar(‘test_value’);”> <div id="optionpanel"> <?php echo "<p> User ".$_SESSION['name']." is logged in. </p>"; ?> <ul> <?php if($_SESSION['accesslevel'] >= 1){ ?><li><a href="/login/comics/upload.php">Upload a comic</a></li><?php } ?> <?php if($_SESSION['accesslevel'] >= 1){ ?><li><a href="/login/comics/comiclist.php">Edit a comic</a></li><?php } ?> <?php if($_SESSION['accesslevel'] >= 2){ ?><li><a href="/login/blog/newblog.php">Write a new blog</a></li><?php } ?> <?php if($_SESSION['accesslevel'] >= 2){ ?><li><a href="/login/blog/bloglist.php">Edit a blog</a></li><?php } ?> <li><a href="user/uploadimage.php">Upload a profile picture</a></li> <li><a href="user/edituser.php">Edit my profile</a></li> <?php if($_SESSION['accesslevel'] >= 4){ ?><li><a href="/login/user/userlist.php">Edit another profile</a></li><?php } ?> <?php if($_SESSION['accesslevel'] >= 3){ ?><li><a href="/login/mail/mailinglist.php">Send an email to all the artists</a></li><?php } ?> <?php if($_SESSION['accesslevel'] >= 5){ ?><li><a href="/login/magic.php">View server information</a></li><?php } ?> <li><a href="logout.php">Logout</a></li> </ul> </div> <div id="todo"> <pre> <?php if($_SESSION['accesslevel'] >= 1){ include("TODO.txt"); } ?> </pre> </div> </body> </html> EDIT: Just noticed that logging in to optionpanel.php works now on a www. domain after the ini_set('session.cookie_domain', '.domain.co.uk'); ...stupid not to notice that. Wouldn't appear to be reliant on the www. part, since I have a page which works either way. Also, register_globals is currently set to OFF. Quote Link to comment Share on other sites More sharing options...
StevieC87 Posted January 4, 2023 Share Posted January 4, 2023 I had the same issue, and in my case I had a php.ini file that wasn't being applied to the subfolders. I did phpinfo and you can see it there: Loaded Configuration File . Then I compared both pages, the one in the main directory, and the one in the subdirectory (where the session wasn't being loaded), and the subdirectory was using another php.ini (the default from the host). Because in the php.ini you define the tmp folder where the session is saved. So then i added this to .htaccess so my custom php.ini file was accessible for the subdirectories <IfModule mod_suphp.c> suPHP_ConfigPath /home/USERNAME/PATH/TO/INI/ </IfModule> Ok hope this helps! Quote Link to comment Share on other sites More sharing options...
ginerjm Posted January 4, 2023 Share Posted January 4, 2023 A 12 YEAR OLD POST REALLY SHOULD NOT BE OPENED UP. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.