Jump to content

Recommended Posts

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.

 

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.

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...

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?

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.

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

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.

 

 

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.

 

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.

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.

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>");
}

 

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.

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.

  • 12 years later...

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!

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.