Jump to content

Session not recognised on first attempt at logging in


Jonline

Recommended Posts

I've come across a problem within (at least) Google Chrome and Safari.

 

Upon the first attempt at logging in, the user is not redirected. The session is created, but it is almost as if it is not detected, and takes the user back to the index page. Upon a second attempt, the correct redirect is issued and the user is taken to the correct page.

 

The script works fine in Firefox, and I have checked extensively to see if the correct data is being returned, which it is. I've searched and I've searched and I've searched, but unfortunately nothing of use has cropped up.

 

Access.php - User logging in

 

<?php
session_start();
ob_start();

include_once('db.class.php');
include_once('register.class.php');
include_once('login.class.php');

$db = null;
$reg = null;
$log = null;

$db = new Database();
$log = new Login($db, null, null, null, null, null, null);

if (isset($_SESSION['login'])) {
$log->redirectUser($_SESSION['login']);
}

include_once('includes/header.html');
?>
Some HTML...
<?php
if (isset($_POST['logsub'])) {
 $db = new Database();
 $log = new Login($db, $_POST['email'], $_POST['pass']);
 $validation = &$log->validate();
 if(empty($validation)) {
	 $log->redirectUser($_SESSION['login']);
 } else {
	 echo "<div id='error'><div class='box-error'><p style='font-weight: bold'>The following errors occured...</p><ul>";
		 for ($i = 0; $i < count($validation); $i++) {
			 echo "<li>" . $log->getErrorMessage($validation[$i]) . "</li>";
		 }
	 echo "</ul></div></div>";
 }
}
?>

 

Login.class.php - Login class

 

// Validate the credentials given
public function validateLogin() {

// Hash the plain text password
 $this->hashedPass = $this->hashPassword();
 try {
      $query = $this->dbcon->prepare("SELECT Login_ID, Login_Email, Login_Password FROM Login WHERE Login_Email = :email AND Login_Password = :pass");
      $query->bindParam(':email', $this->email, PDO::PARAM_STR);
      $query->bindParam(':pass', $this->hashedPass, PDO::PARAM_STR);
 	 $query->execute();
 	 $fetch = $query->fetch(PDO::FETCH_NUM);
 	 $this->loginid = $fetch[0];
      // If a match is found, create a session storing the login_id for the user
      if ($query->rowCount() == 1) {
	      $_SESSION['login'] = $this->loginid;
	      session_write_close();
      } else {
	      return LOG_ERR_NO_MATCH;
      }
 } catch (PDOException $e) {
 	 $this->dbcon->rollback();
      echo "Error: " . $e->getMessage();
 }
}

// Fetch the customer ID
private function getCustId() {
 try {
 	 $query = $this->dbcon->prepare("SELECT Customer.Cust_ID FROM Customer JOIN Login ON Customer.Login_ID = Login.Login_ID WHERE Customer.Login_ID = :loginid");
 	 $query->bindParam(':loginid', $this->loginid, PDO::PARAM_INT);
 	 $query->execute();
 	 $fetch = $query->fetch(PDO::FETCH_NUM);	
 	 return $fetch[0];
 } catch (PDOException $e) {
 	 $this->dbcon->rollback();
 	 echo "Error: " . $e->getMessage();
 }
}

// Check the registration progress - are they verified? paid?
// This function is used elsewhere hence the $sessionid argument
public function checkRegistration($sessionid) {
 $this->loginid = $sessionid;
 $this->custid = $this->getCustId();
 try {
	  $queryVer = $this->dbcon->prepare("SELECT Cust_ID FROM Customer_Verify_Email WHERE Cust_ID = :custid");
 	 $queryVer->bindParam(":custid", $this->custid, PDO::PARAM_INT);
 	 $queryVer->execute();
      $queryFee = $this->dbcon->prepare("SELECT Cust_ID FROM Initial_Fee_Payment WHERE Cust_ID = :custid");
 	 $queryFee->bindParam(":custid", $this->custid, PDO::PARAM_INT);
      $queryFee->execute();
      // If a record exists in the verify table, return the value 1. This means the user has not yet verified their email.
      if ($queryVer->rowCount() == 1) {
	      return 1;
      } else {
	      // If a record does not exist in the payment table, no payment has been made. Return 2.
	      if ($queryFee->rowCount() == 0) {
	     	 return 2;
	      // Otherwise, email is verified and the payment has been made.
	      } else {
		      return 0;
	      }
      }
 } catch (PDOException $e) {
 	 $this->dbcon->rollback();
      echo "Error: " . $e->getMessage();
 }
}

// Redirect the user accordingly
public function redirectUser($sessionid) {
 $this->loginid = $sessionid;
 $logNum = $this->checkRegistration($this->loginid);
 if ($logNum == 0) {
 	 header("Location: http://www.jonline.me.uk/fbedder/details.php", true, 200);
 	 exit();
 } else if ($logNum == 1) {
 	 header("Location: http://www.jonline.me.uk/fbedder/verification.php", true, 200);
 	 exit();
 } else if ($logNum == 2) {
      header("Location: http://www.jonline.me.uk/fbedder/payment.php", true, 200);
      exit();
 }
}

 

Here's a link to the site: http://www.jonline.me.uk/fbedder/ -> I have set-up a test account with the credentials -> email: test@jonline.me.uk / password: test123321

 

To reiterate, the problem exists only in Google Chrome and Safari (the Safari being on my iPhone) and lies purely within the logging in aspect. On the first attempt, the session will be ignored (it is created), and on the second attempt, the user will be redirected.

 

Any ideas? I've tried a multitude of possibilities...

 

Thanks

Edited by Jonline
Link to comment
Share on other sites

Can't edit the main post, sorry. I've found the ultimate cause:

 

When the redirect is called, it sends the user to the details.php page. However, this page contains the following snippet of code:

 

if (!isset($_SESSION['login'])) {
header("Location: http://www.jonline.me.uk/fbedder/index.php");
}

 

Obviously what is happening, is that the session is not being detected / saved / "whatevered", and as a result is sending the user back to the index page. Is there are a way to ensure the $_SESSION is not effectively lost. I had read about this before posting here, and is why I inserted session_write_close(), but that doesn't seem to be doing the desired effect.

 

Any ideas?

 

--

 

 

After diagnosing the problem being within the fact the $_SESSION variable was effectively being lost, I read up about the session_write_close() function and came across this comment:

My sessions were screwing up because I had 2 different session IDs going at once:
  • 1 PHPSESSID cookie for domain.com
  • 1 PHPSESSID cookie for www.domain.com

This fixed it:

//At the beginning of each page...

session_set_cookie_params (1800,"/","domain.com");

session_start();

 

Source: http://pt2.php.net/m...close.php#84925

 

Setting the parameters resolved the issue.

Edited by Jonline
Link to comment
Share on other sites

You need an exit; statement after your header() redirect to prevent the remainder of the code on your page from running while the browser is requesting the target of the redirect. You likely have some code that is clearing the session variables.

 

Another possibility is that the variation of your domain name (www. vs no www. on it) is changing from the starting page to the final page and the session id cookie is not set up to match all variations of your domain. For the devices where it does work, you are using all the same variation. For the ones where it does not work, you are likely starting out using one variation (without the www. on it), but the header() redirect takes you to the variation with the www. on it, then you stay on that variation and the session matches.

Link to comment
Share on other sites

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.