Session not recognised on first attempt at logging in - php

Issue resolved - see: https://stackoverflow.com/a/14719452/1174295
--
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: fbedder/details.php", true, 200);
exit();
} else if ($logNum == 1) {
header("Location: fbedder/verification.php", true, 200);
exit();
} else if ($logNum == 2) {
header("Location: fbedder/payment.php", true, 200);
exit();
}
}
Here's a link to the site: fbedder/ -> I have set-up a test account with the credentials -> email: test# / 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...
-- Edit --
I know where the issue lies now.
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: 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.

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/manual/en/function.session-write-close.php#84925
Setting the parameters resolved the issue.

Related

Matching user code with database and redirecting winners / losers

I am new to...well everything. Bear with me.
I have a website that has a textbox for user input ( a code they receive). When they submit, it sends the code to a PHP file, which then checks the code against a database. If it matches the winner code, it redirects the user to a specific page. Losers, are redirected to a loser page.
That works!
However, I'm now trying to redirect users to a third page, if their code matches a different table of codes, but I can't figure out the if else statements. Can anyone help a poor doodle like myself? Thanks!
Here's what I got:
// Connect to your MySQL database
$dbhst = "localhost";
$dbnme = "blah";
$bdusr = "blaaah";
$dbpws = "blahblahblacksheep";
// Using PDO to connect
$conn = new PDO('mysql:host='.$dbhst.';dbname='.$dbnme, $bdusr, $dbpws);
// Getting variables
$answer = $_POST['answer'];
$questionID = $_POST['questionID'];
// Comparing answers
try {
$stmt = $conn->prepare("SELECT * FROM Winners WHERE Winners='" . $answer . "' LIMIT 0,1");
$stmt->execute();
$result = $stmt->fetchAll();
if ( count($result) ) {
foreach($result as $row) {
// echo 'Congrats, you've entered a correct code';
header("Location: https://get-a-brik.myshopify.com/pages/8522");
}
} else {
// echo 'Your code did not win. Please try again.';
header("Location: https://get-a-brik.myshopify.com/pages/5551");
exit;
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
You can use an if ... else if ... else statement:
if (... user is winner ...) {
header("Location: https://get-a-brik.myshopify.com/pages/8522");
} else if (... user is looser ...) {
header("Location: https://get-a-brik.myshopify.com/pages/5551");
} else {
header("Location: winner page");
}

Get int from column by using email to identify row

I want to get and echo a users permission level.
I have a function where the users email is passed, the function then needs to get the users permission level and return it, so it can be echoed on another page.
I imagine the function will look though the database for the passed email, it then finds the users permission and returns with that.
In the 'User.class.php'
public static function permGetter($email)
{
try
{
$db = Database::getInstance();
$stmt = $db->prepare('SELECT permission FROM users WHERE email = :email LIMIT 1');
$stmt->execute([':permission'=>$permission]);
$user = $stmt->fetchObject('User');
if($user !== false)
{
return $permission;
}
}
catch (PDOException $exception)
{
error_log($exception->getMessage());
return false;
}
}
In the 'permRequest.php'
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once("../includes/init.php");
//Get passed from an external program
$email = $_GET['email'];
$pass = $_GET['pass'];
if($email && $pass !== null)
{
// Checks if the user's entered credential matches with those in database
if(Auth::getInstance()->login($email, $pass))
{
//Uses the passed email to get permission level in 'User.class.php'
if(User::permGetter($email))
{
echo 'Permission ' + (int) $permission;
}
}
else
{
//I use level 5 as a debug so i can see when it fails
echo 'Permission 5';
}
}
?>
Database
Here's an example on what my database looks like.
Edit 1
Okay messing about, I think i got closer to the solution.
First, #Lawrence Cherone, thanks for pointing out my mistake in my execute.
Okay I have changed my code in
User.class.php
public static function permGetter($email, $permission)
{
try
{
$db = Database::getInstance();
$stmt = $db->prepare('SELECT permission FROM users WHERE email = :email');
$stmt->execute([':email'=>$email]);
$row = $stmt->fetch(PDO::FETCH_NUM);
$permission = $row['permission'];
}
catch (PDOException $exception)
{
error_log($exception->getMessage());
return false;
}
}
I have made small changes to
permRequest.php
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once("../includes/init.php");
//Get passed from an external program
$email = $_GET['email'];
$pass = $_GET['pass'];
$permission = '';
if($email && $pass !== null)
{
// Checks if the user's entered credential matches with those in database
if(Auth::getInstance()->login($email, $pass))
{
//Uses the passed email to get permission level in 'User.class.php'
if(User::permGetter($email, $permission))
{
echo 'Permission ', $permission;
}
}
}
?>
But now i get an error. The error is this Notice: Undefined index: permission in /classes/User.class.php on line 56
So, I read up on it and it seemed like it should be emptied first, so I empty it in permRequest.php that's why I'm passing it too, but I still get this error after i emptied it?
However if i change
$row = $stmt->fetch(PDO::FETCH_NUM);
to
$row = $stmt->fetch(PDO::FETCH_ASSOC);
/* OR */
$row = $stmt->fetch(PDO::FETCH_BOTH);
I get no error but it simply says my email or password is incorrect, which it isn't I have double and triple checked it.
So I'm confused to which PDO::FETCH_ I should use. I have read this (Click here) and I would say that both ASSOC, BOTH and NUM would fit the purpose.
So why is one giving an error while the two other's simply fails the login?
Edit 2
Found the solution and i have written it as a Answer. Can't accept it for the next two days however.
I moved everything out of the User.class.php and moved it into permRequest.php. This solved my problem for some reason. So my code looks like this now
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL ^ E_NOTICE);
require_once("../includes/init.php");
$email = $_GET['email'];
$pass = $_GET['pass'];
if($email && $pass !== null)
{
if(Auth::getInstance()->login($email, $pass))
{
try
{
$db = Database::getInstance();
$stmt = $db->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute([':email' => $email]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$sub = $row['permission'];
echo 'Permission ', $sub;
}
catch (PDOException $exception)
{
error_log($exception->getMessage());
return false;
}
}
}
And I don't use the User.class.php for this function.
So my guess is something went wrong when returning $sub when it was in User.class.php

Strange Password_Hash Issue

So im using the exact same script as I used to a while back and for some reason when I move to my new domain and hosting it is having really weird issues, I created a user and got hm to try login, It wasnt working for him I got a new hash from a random test.php file with this php:
<?php
/**
* In this case, we want to increase the default cost for BCRYPT to 12.
* Note that we also switched to BCRYPT, which will always be 60 characters.
*/
$options = [
'cost' => 9,
];
echo password_hash("His Pass", PASSWORD_BCRYPT, $options)."\n";
?>
It then worked, He logged in fine and I then tried to login to my main admin account and for some reason its now not working even when I try remaking the hash 2 times now.
I have no idea whats going on can someone please enlighten me.
Heres the login code:
//If User Submits Form continue;
if(isset($_POST['username'])) {
//If the captcha wasn't submitted;
if(empty($_POST['g-recaptcha-response'])) {
//And theres already a try with there IP;
if($trycount != '0') {
//Increment there try count and give a notification;
updateTries(); ?>
<script type="text/javascript">localStorage.setItem("notification", "nocaptcha");</script> <?php
//If there isn't a try on there IP yet;
} else {
//Add one try and give a notification;
addTry(); ?>
<script type="text/javascript">localStorage.setItem("notification", "nocaptcha");</script> <?php
}
//If the captcha was submitted;
} else {
//Set captcha variable to the Submitted Captcha Response;
$captcha=$_POST['g-recaptcha-response'];
//Captcha Verification Url;
$url = 'https://www.google.com/recaptcha/api/siteverify?secret=t&response=';
//JSON Encode the Captcha's response and Site IP;
$response = json_decode(file_get_contents($url.urlencode($captcha).'&remoteip='.$_SERVER['REMOTE_ADDR']), true);
//If the captcha wasn't verified;
if($response['success'] == false) {
//And theres already a try with there IP;
if($trycount != '0') {
//Increment there try count and give a notification;
updateTries(); ?>
<script type="text/javascript">localStorage.setItem("notification", "captchafailed");</script> <?php
//If there isn't a try on there IP yet;
} else {
//Add one try and give a notification;
addTry(); ?>
<script type="text/javascript">localStorage.setItem("notification", "captchafailed");</script> <?php
}
//Otherwise if it was verified;
} else {
//Try log in with the given details;
user_login($_POST['username'],$_POST['password']);
//If logged in redirect and give a notification;
if(loggedin()) { ?>
<script type="text/javascript">localStorage.setItem("notification", "loggedin");</script>
<meta http-equiv="refresh" content="0;URL='https://gameshare.io'" /> <?php
} else {
//And theres already a try with there IP;
if($trycount != '0') {
//Increment there try count and give a notification;
updateTries(); ?>
<script type="text/javascript">localStorage.setItem("notification", "loginfailed");</script> <?php
//If there isn't a try on there IP yet;
} else {
//Add one try and give a notification;
addTry(); ?>
<script type="text/javascript">localStorage.setItem("notification", "loginfailed");</script> <?php
}
}
}
}
}
User_login function:
//Create a new function named user_login;
function user_login($username = false, $password = false) {
//Fetch for the username and password applied;
$st = fetch("SELECT username,password,email,image FROM users WHERE username = :username",array(":username"=>$username));
//If a row was found continue
if($st != 0) {
$storedhash = $st[0]['password'];
if (password_verify($password, $storedhash)) {
//Set a new username session and set it the username;
$_SESSION['username'] = $username;
$_SESSION['email'] = $st[0]['email'];
$_SESSION['image'] = $st[0]['image'];
if($username == 'admin') {
$_SESSION['role'] = 'admin';
} else {
$_SESSION['role'] = 'user';
}
}
}
//If no errors happened Make the $valid true;
return true;
$dontaddtry = true;
}
Fetch function:
//Create a new function named fetch;
function fetch($sql = false,$bind = false,$obj = false) {
//Prepare The SQL Query;
$query = Connect()->prepare($sql);
//Execute Binded Query;
$query->execute($bind);
//While Fetching Results;
while($result = $query->fetch(PDO::FETCH_ASSOC)) {
//Add a row to the results respectiveley;
$row[] = $result;
}
//If there are no rows;
if(!empty($row)) {
//Make it an object;
$row = ($obj)? (object) $row : $row;
} else {
//Else row is false;
$row = false;
}
//If no errors happened Make $row true;
return $row;
}
Connect Function:
//Create a new function named LoggedIn, And apply database info;
function Connect($host = 'localhost',$username = 'x',$password = 'x',$dbname = 'x') {
//Try execute the PHP with no errors;
try {
//Create a PDO Session;
$con = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
//Session Attributes;
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
//Catch all PDOException errors;
catch (PDOException $e) {
//If any errors print result;
echo "<code><pre>".print_r($e)."</pre></code>";
//Make the PDO session false;
$con = false;
}
//If no errors happened Make the PDO session true;
return $con;
}
P.S If you wish to get an account to try on my site let me know and ill make a temporary account.
Make sure your the php version of your new hosting. password_hash needs at-least PHP 5.5.0.
You can check your current PHP version via following code.
<?php
echo 'Current PHP version: ' . phpversion();
?>

PHP If Statements Not Firing

I'm currently building a system for a football league. And are currently working on the script file for adding results. Most of the script works and the result is always successfully added to the database. However the authentication part seems to fail. The if statement on line 12 does not seem to fire and I can't understand why.
My code can be found in the pastebin link here: http://pastebin.com/ty4pdGgn
<?PHP
include 'functions.php';
dbConnect();
//$userEmail = mysql_real_escape_string($_POST["userEmailText"]);
$userCode = mysql_real_escape_string($_POST["userPasscodeText"]);
$authenticated = false;
$userEmail = "info#example.com";
if ($userEmail == "info#example.com") {
header('Location: ../results.php?error=authentication');
}
$allUsers = mysql_query("SELECT * FROM accounts WHERE email = '$userEmail'");
while ($thisUser = mysql_fetch_assoc($allUsers)){
if ($userCode != $thisUser['passCode']) {
header('Location: ../results.php?error=authentication2');
}
echo $thisUser['passCode'];
$authenticated = true;
$userID = $thisUser['userID'];
}
if (!$authenticated) {
header('Location: ../results.php?error=authentication3');
}
$dateSubmitted = $_POST['submissionDate'];
$homeTeam = $_POST['homeTeam'];
$awayTeam = $_POST['awayTeam'];
$homeGoals = $_POST['homeGoals'];
$awayGoals = $_POST['awayGoals'];
if ($homeTeam == $awayTeam) {
header("Location: ../results.php?error=team");
}
if (getTeamLeague($homeTeam) != getTeamLeague($awayTeam)) {
header("Location: ../results.php?error=league");
} else {
$leagueID = getTeamLeague($homeTeam);
}
if ($homeGoals > $awayGoals) {
$winnerID = $homeTeam;
} else if ($homeGoals < $awayGoals) {
$winnerID = $awayTeam;
} else if ($homeGoals == $awayGoals) {
$winnerID = -1;
}
$cQuery = mysql_query("INSERT INTO results VALUES ('', $userID, '$dateSubmitted', $leagueID, $homeTeam, $homeGoals, $awayTeam, $awayGoals, $winnerID, 0)");
if ($cQuery){
header('Location: ../results.php');
} else {
echo mysql_error();
}
?>
Any help with this matter will be much appreciated. The functions.php contains no errors as this is all to do with database entry and not the authentication.
Put a die(); after the header("Location:...");
As your comparison code (the "if" part on line 12) that you pasted has to work, i have two advice:
Put a die(); or exit(); after the header() part.
Try looking here, as I am not sure if header() will work, while the location path you set is relative. Basic advice is to always use base paths for redirects, like "http://your.site.com/script.php").

PHP+MySQL website (localhost) working with netbeans xdebug, but NOT ALONE

Okay, this may sound off-topic, but I want to know if someone have had similar experience and if they found the problem/solution.
Sorry this post has grown more like self try-and-error raportting, cause no one have answered. I have added status updates of problem solving in bottom of question.
For a moment the problem seems to be my database update query.
I'm developing PHP+MySQL website on netbeans 7.3. + XAMPP. Everything was working fine. No suddenly my log-in form (suppose to save some $_SESSION variables and redirect to page) is not working.
Strange thing is that when I debug with Netbeans + Xdebug all goes fine. Session variables are set and page forwarded correctly.
Question: Does someone faced similar problem? Has anyone idea what could be going wrong?
I only can suppose something in system is set differently when I run xdebug. (But the exact(?) same log-in was working fine few days ago).
I have tried lot of things (many many hours but most of them don't come to my mind now). I tried to move the page on remote server and same behavior continues.
(If you want more info ask and I'll edit.)
Hope someone has ideas!
EDIT: I think has something to do with my php-session variables. I realized that while Xdebug the site starts with empty php-session variables, so it does use/get same ones it normally has (?)
The code is creating sessions to database, but it does not get to the next step to set the php-session variables. (Check out the place in index.php marked as /* HERE IS THE PLACE */
Okay. HERE IS STRIPPED CODE (working with netbeans+xdebug, not alone):
index.php:
<?php
//Open PDO connection to MySQL server: $db_con
$db_connection = $_SERVER['DOCUMENT_ROOT'] . '/test-login/db.php';
require $db_connection;
session_start();
//******************************************************************************
//Helping functions
function convert_time_to_utc_date ($UNIX_timestamp) {
return gmdate("Y-m-d H:i:s", $UNIX_timestamp);
}
//******************************************************************************
// Function to authenticate user with username and password. returns FALSE if not authenticated and TRUE if successful authentication
function authenticate_username_password($db_con, $usernm, $passwd)
{
try {
$stmt = $db_con->prepare("SELECT id, hashed_pwd, COUNT(*) AS usercount FROM gui_users WHERE username=? AND not_in_use = 0 AND deleted = 0");
$stmt->execute(array($usernm));
if($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if($row['usercount'] == 1){
if(crypt($passwd, $row['hashed_pwd']) == $row['hashed_pwd']){
$user_id = $row['id'];
session_regenerate_id(true);
$new_session_id = session_id();
$remote = true;
$datenow = convert_time_to_utc_date(time());
$stmt = $db_con->prepare("INSERT INTO gui_sessions (session_id,user_id,starttime_UTC,lastused_UTC,remote) VALUES (?, ?, ?, ?, ?)");
$stmt->execute(array($new_session_id, $user_id, $datenow, $datenow, $remote));
return $user_id;
}
}
}
return FALSE;
} catch (PDOException $e) {
return FALSE;
}
}
//******************************************************************************
//Function to get user roles
function get_user_roles(PDO $db_con, $user_id)
{
try {
$stmt = $db_con->prepare("SELECT role_id, role_last FROM gui_users WHERE id = ?");
$stmt->execute(array($user_id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return array('max_role_id' => $row['role_id'], 'last_role_id' => $row['role_last']);
} catch (PDOException $e) {
return FALSE;
}
}
//******************************************************************************
// Function to handel sessions, log in and log out
function authenticate(PDO $db_con) {
//********************
// If action is LOG IN
if (isset($_POST['action']) and $_POST['action'] == 'login') {
if (!isset($_POST['username']) or $_POST['username'] == '' or !isset($_POST['passwd']) or $_POST['passwd'] == '') {
$GLOBALS['loginError'] = 'Please fill in both fields';
return FALSE;
}
$user_id = authenticate_username_password($db_con, $_POST['username'], $_POST['passwd']);
if ($user_id !== false && $user_id > 0) {
$_SESSION['reloadcounter'] = 1;
$_SESSION['username'] = $_POST['username'];
$_SESSION['user_id'] = $user_id;
$_SESSION['user_def_page'] = 1; //get_user_default_page($db_con, $user_id);
$user_roles = get_user_roles($db_con, $user_id);
$_SESSION['max_role_id'] = $user_roles['max_role_id'];
$_SESSION['sel_role_id'] = $user_roles['last_role_id'];
$goto = isset($_POST['goto']) ? $_POST['goto'] : HTTPS_SERVER;
header('Location: ' . $goto);
exit;
} else {
$GLOBALS['loginError'] = 'Wrong username or password!';
return FALSE;
}
}
//*********************
// If action is LOG OUT
if (isset($_POST['action']) and $_POST['action'] == 'logout') {
$user_ses_id = session_id();
try {
$stmt = $db_con->prepare("DELETE FROM gui_sessions WHERE session_id=?");
$stmt->execute(array($user_ses_id));
} catch (PDOException $e) {
log_error('PDO_CONN', $e->getCode(), $e->getMessage(), TRUE, $db_con);
}
session_regenerate_id(true);
unset($_SESSION['reloadcounter']);
unset($_SESSION['username']);
unset($_SESSION['user_id']);
unset($_SESSION['user_def_page']);
unset($_SESSION['max_role_id']);
unset($_SESSION['sel_role_id']);
$goto = isset($_POST['goto']) ? $_POST['goto'] : HTTPS_SERVER;
header('Location: ' . $goto);
exit;
}
//************************************
// If no action see if user logged in
$user_ses_id = session_id();
$datenow = convert_time_to_utc_date(time());
try {
$stmt = $db_con->prepare("UPDATE gui_sessions SET lastused_UTC=? WHERE session_id=?");
$stmt->execute(array($datenow, $user_ses_id));
if ($stmt->rowCount() == 1) {
return TRUE;
} else {
unset($_SESSION['reloadcounter']);
unset($_SESSION['username']);
unset($_SESSION['user_id']);
unset($_SESSION['user_def_page']);
unset($_SESSION['max_role_id']);
unset($_SESSION['sel_role_id']);
return FALSE;
}
} catch (PDOException $e) {
log_error('PDO_CONN', $e->getCode(), $e->getMessage(), TRUE, $db_con);
if (DEBUG_ON) {
echo 'SESSION UPDATE FAILED<br>';
}
return FALSE;
}
}
//******************************************************************************
//SESSION CONTROL
if (!authenticate($db_con)) {
include 'login.html.php';
exit();
}
include 'page.html.php';
?>
login.html.php:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p class="login-error"><?php if(isset($loginError)) { echo $loginError; } else { echo ' '; } ?></p>
<form id="login" action="" method="POST" name="login">
<label for="username">Username:</label><br />
<input name="username" type="text" size="40" value="" tabindex="0" /><br />
<label for="passwd">Password:</label><br />
<input name="passwd" type="password" size="40" value="" tabindex="1" /><br />
<input type="hidden" name="goto" value="https://localhost/test-login/"/>
<input type="hidden" name="action" value="login"/>
<input type="submit" class="button login" value="Login" tabindex="2"/><br />
</form>
<div><?php echo '<pre>' . var_dump($_SESSION) . '</pre>'; ?></div>
</body>
</html>
page.html.php:
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<h1>Hello world!</h1>
<?php echo '<pre>' . var_dump($_SESSION) . '</pre>'; ?>
</div>
</body>
</html>
EDIT: I have track the error more and it seems that while Xdebuging the $_POST variables are okay, but standalone PHP interpreter is losing them some how.
Strange is also that I create the session to database inside if(isset($_POST['action']) && $_POST['action'] == 'login') and the php does not seem to get in there but it is able to Insert the session in database inside that if clause.
EDIT: Braking this till very peaces helped me to found one big mistake which still should not affect to the ACTUAL problem but made it much more harder to found.
Cause I have forgot to add curly brackets to if-else in the end of authenticate, the function always unset the session variables. In the beginning I thought that the function is not able to set them but it's actually unsetting them after redirection to "$_SERVER['PHP_SELF']". Anyway this should not happen if the UPDATE gui_session statement would work. But it made it much harder to see where is the problem. Here is the correction for index.php:
//************************************
// If no action see if user logged in
$user_ses_id = session_id();
$datenow = convert_time_to_utc_date(time());
try {
$stmt = $db_con->prepare("UPDATE gui_sessions SET lastused_UTC=? WHERE session_id=?");
$stmt->execute(array($datenow, $user_ses_id));
if ($stmt->rowCount() == 1) {
return TRUE;
} else {
unset($_SESSION['reloadcounter']);
unset($_SESSION['username']);
unset($_SESSION['user_id']);
unset($_SESSION['user_def_page']);
unset($_SESSION['max_role_id']);
unset($_SESSION['sel_role_id']);
return FALSE;
}
} catch (PDOException $e) {
log_error('PDO_CONN', $e->getCode(), $e->getMessage(), TRUE, $db_con);
if (DEBUG_ON) {
echo 'SESSION UPDATE FAILED<br>';
}
return FALSE;
}
The problem is that this update fails. But i have no idea why.
$stmt = $db_con->prepare("UPDATE gui_sessions SET lastused_UTC=? WHERE session_id=?");
$stmt->execute(array($datenow, $user_ses_id));
if ($stmt->rowCount() == 1) {
return TRUE;
}
If I try in php myadmin:
UPDATE gui_sessions
SET lastused_UTC='2013-08-04 12:00:00'
WHERE session_id='03dfgpiu1jl8idcjf191hqv4m2'
It affects 0 row, but if i do:
SELECT *
FROM gui_sessions
WHERE session_id='03dfgpiu1jl8idcjf191hqv4m2'
It returns 1 row
Okay. Problem solved. I'll leave the answer here if someone somehow runs to similar problem. I still don't know what the Xdebug did to hide this problem.
The problem was that I was trying to authenticate user by updating the last_used field in database session table. I assumed that if query is able to update that field the session must be valid. So I check if sql update last_user rows affected equals to 1, then users php-session-id is in session table. Problem is that MySQL returns 0 rows affected if the field has already the value that is updated "reference". And in my case that's of course true, cause the session last_update field is just created in log in procedure.
BUT it was very painful to find the problem cause Xdebug was doing something very strange there and after 0 rows affected update query it jumped out of the function without going to the else statement of the if-clause where I check if the number of affected rows equals to 1.
Comment if you have idea why Xdebug was behaving this way.

Categories