$_SESSION variables not working

impressionexpress
impressionexpress used Ask the Experts™
So I have a login area which only seems to work in Firefox

its setting the variables but I appear to be losing the session somehow

from the login page, I do an AJAX call to the login.php file which checks the database and the status of the user, if all is good, I return true and AJAX changes the page location to the secured area. at the top of each page in the secured area, I check for $_SESSION['userID'] if its not set or empty it brings you back to the login page which is happening in every browser except for firefox ???
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Can you provide a URL where we can see this happen? Or can you at least provide the code? There's not much we can do without it.

When you say "every browser except Firefox", are you referring to IE and Chrome? Or what other browsers are you testing?

There are not too many "compatibility" differences between IE, Firefox, and Chrome. Off the top of my head:

1. IE and Chrome both use a system proxy, while Firefox has its own proxy settings. If a proxy were interfering with the page load somehow, that could lead to IE and Chrome behaving one way and Firefox behaving another. It's definitely not a common scenario, though.

2. The biggest functional differences between those browsers tends to be in Javascript compatibility, although usually Javascript errors are more likely to present and interfere on IE, whereas Chrome and Firefox are usually a little more forgiving.

Given that you're dealing with an AJAX call, the first thing I would do is load up the developer tools in each browser (F12) and go to the Javascript "Console" area. Then reproduce your issue and check for any JS errors that might appear.

3. There might be some kind of configuration difference leading to session IDs not being sent over properly. Use the Developer Tools in each browser and go to the Network tab. Make sure the "persist" option is checked/enabled, and then reproduce the issue.

Then for each browser, make note of:
1. If a session ID cookie is set when you first log in.
2. If that session ID cookie is sent over in your AJAX call.
The jquery
$( document ).ready( function () {
	var refresh_page = 14; // minutes
	refresh_page = refresh_page * 60000;
	setTimeout(function() {
		location.reload();
	}, refresh_page);

	$("#efm_login").click(function() {
		$(".send_error").html(' ');
		console.log('Button Clicked');
	//	console.log('Posted Data: ' + $("#username").val() + ' ' + $("#password").val());
		var fd = new FormData();
		fd.append('temp_random',$("#temp_random").val());
		fd.append('username',$("#username").val());
		fd.append('password',$("#password").val());
		

		$.ajax({
			url: 'ajax/efm_login.php',
			data: fd,
			contentType: false,
			processData: false,
			type: 'POST',
			dataType: 'JSON'
		}).then(function(resp) {
			console.log('resp: ' + resp);
			if (resp.status){
				window.location.href = resp.url;
			}else{
				$(".send_error").text(resp.error);
			}			
		});
	});
});

Open in new window


login.php
<?php
	error_reporting(E_ALL);
	ini_set('display_errors', 1);
	setlocale(LC_ALL, "en_US.utf8");

	include("../classes/Connection.class.php");
	include("../classes/Cryptor.class.php");
	include("../includes/constants.php");
	include("../includes/functions.php");

	$response = (object) [
	   "status" => false
	];


	if(Cryptor::decrypt($_POST['temp_random'], $_SERVER['REMOTE_ADDR'] . SECRET_KEY) > time() - 60* 15 ) {
		if(!empty($_POST['username']) && !empty($_POST['password'])){
			$result = json_decode(user_login($_POST['username'], $_POST['password']), true);
		//	$response->error = $result['status'] . " " . $result['error'];
			if($result['status']){
				$response->url = "https://admin.domain.com/";
				$response->status = true;				
			}elseif(array_key_exists("error", $result)){
				$response->error = $result['error'];
			}else{
				$response->error = "A system error occured (#L25), please try again." . $result['status'];
			}

		}else{
			$response->error = "Please enter your login credentials before submitting";
		}		
	}else{
		$response->url = "https://admin.domain.com/";
		$response->error = "A system error occured (#L33), please try again.";
	}

	die(json_encode($response));

?>

Open in new window


functions.php
<?php
	error_reporting(E_ALL);
	ini_set('display_errors', 1);
	setlocale(LC_ALL, "en_US.utf8");

	include("../classes/Connection.class.php");
	include("../classes/Cryptor.class.php");
	include("../includes/constants.php");
	include("../includes/functions.php");

	$response = (object) [
	   "status" => false
	];


	if(Cryptor::decrypt($_POST['temp_random'], $_SERVER['REMOTE_ADDR'] . SECRET_KEY) > time() - 60* 15 ) {
		if(!empty($_POST['username']) && !empty($_POST['password'])){
			$result = json_decode(user_login($_POST['username'], $_POST['password']), true);
		//	$response->error = $result['status'] . " " . $result['error'];
			if($result['status']){
				$response->url = "https://admin.domain.com/";
				$response->status = true;				
			}elseif(array_key_exists("error", $result)){
				$response->error = $result['error'];
			}else{
				$response->error = "A system error occured (#L25), please try again." . $result['status'];
			}

		}else{
			$response->error = "Please enter your login credentials before submitting";
		}		
	}else{
		$response->url = "https://admin.domain.com/";
		$response->error = "A system error occured (#L33), please try again.";
	}

	die(json_encode($response));

?>

Open in new window


At the top of every secured page
	if(empty($_SESSION['userId'])){
		header("location: https://www.domain.com/login.php");
		die();
	}

Open in new window

https://admin.somedomain.com

user: disabled
password: disabled

This information has been removed because I found the problem
Most Valuable Expert 2017
Distinguished Expert 2018
Not sure if this is relevant but I had a similar issue with Chrome.

The problem I had was that I was using a CSRF token that was generated when the login form was generated.

My AJAX was sending this to the backend and the login request was failing.

When I debugged it I found the CSRF token sent did not match the one stored in the session.

Further investigation showed that Chrome was making a request for a favicon (which it does automatically irrespective of whether this is specified in the page) and my .htaccess was redirecting file not found to index.php which was then redirecting to the login page which was generating a new CSRF.

The fix was to put the favicon file on the server OR change the .htaccess to ignore that request.

I can't say if that is your problem here but it is something to check.
It's the same with IE and opera. The only browser it's working properly is Firefox  the session variable is getting set but gets unset somewhere. I'm wondering if it's because of the AJAX call using .then() and datatype json. It didnt seem to do this prior. I was using success
Most Valuable Expert 2017
Distinguished Expert 2018
I'm wondering if it's because of the AJAX call using .then() and datatype json. It didnt seem to do this prior.
It is not the AJAX call implementation - that has no effect on the server state.

Check your Network tab to see what other requests are being made to the server - somewhere a request is executing that is calling something on the server that is clearing / resetting the SESSION.
The other thing it might be, the session variables are created on domain.com and the secured pages are on subdomain.com ??
That was exactly the issue. I added the following to my sessions.php file
session_set_cookie_params(0, '/', '.domain.com');

Open in new window

Yep that would do it although I'm surprised that Firefox would allow that.

Cookie scope should be standard across all browsers.
I think that it was still working at one point because the cache was not cleared
Most Valuable Expert 2017
Distinguished Expert 2018
the session variables are created on domain.com and the secured pages are on subdomain.com
That should have been stated up front - it would have given us the opportunity to find the problem a lot quicker.
Sorry Julian, I didn't think that would be an issue. as soon as I thought of it might be the issue, I googled it and saw I wasn't the only one with this issue and saw some fixes, when applied... all started to work!

Thank you
session_set_cookie_params(0, '/', '.domain.com');

Open in new window

Most Valuable Expert 2017
Distinguished Expert 2018
Sorry Julian, I didn't think that would be an issue. as soon as I thought of it might be the issue
No problem - just remember that with Web the domain, port and protocol are all VERY important for a range of topics.

When dealing with these issues it is important to highlight what you are using for each.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial