I have spent a couple of months developing an application on a domain of mine. It's overall a simple concept. During development I hosted it myself on my own domain, but recently pushed it to our actual one. The problem is that sessions aren't created or kept between pages, and I can't for the life of me figure out why.
Apologize for the wall of code below, but I prefer it over a theoretical explanation.
Lets start with how I start my session at the top of every page:
function sec_session_start() {
$session_name = 'login';
$secure = false;
$httponly = true;
ini_set('session.use_only_cookies', 1);
session_set_cookie_params(86400, '/', '.domain.com', $secure, $httponly);
session_name($session_name);
session_start();
session_regenerate_id();
}
And then how I check if the user is logged in. I added return x;
instead of false
for debugging. I append this to the redirect URL.
function login_check($mysqli) {
if(isset($_SESSION['id'], $_SESSION['login_string'], $_SESSION['type'])) {
$id = $_SESSION['id'];
$login_string = $_SESSION['login_string'];
$user_browser = $_SERVER['HTTP_USER_AGENT'];
if($_SESSION['type'] == 1 || $_SESSION['type'] == 2) // Admin user
{
if ($stmt = $mysqli->prepare("SELECT `password` FROM `users` WHERE `id` = ? LIMIT 1")) {
$stmt->bind_param('s', $id);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 1) {
$stmt->bind_result($password);
$stmt->fetch();
$login_check = hash('sha512', $password.$user_browser);
if($login_check == $login_string) {
return true;
} else {
return 1;
}
} else {
return 2;
}
} else {
return 3;
}
} else if($_SESSION['type'] == 3) { // Standard user
if($stmt=$mysqli->prepare("SELECT `password` FROM `proj` WHERE `id` = ? LIMIT 1"))
{
$stmt->bind_param("s", $_SESSION['id']);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows == 1)
{
$stmt->bind_result($db_key);
$stmt->fetch();
$login_check = hash('sha512', $db_key.$user_browser);
if($login_check == $login_string) {
return true;
} else {
return 4;
}
}
}
} else {
return 5;
}
} else {
return 6;
}
}
I have two login pages, one for admins and one for users.
Admin:
<?php
ini_set('display_errors','On');
error_reporting(E_ALL);
include_once "../functions.php";
include_once "../db_connect.php";
sec_session_start();
if(login_check($mysqli) === true) {
header('Location: ../index.php');
}
else
{
// Login form
}
Users:
<?php
ini_set('display_errors','On');
error_reporting(E_ALL);
include_once "../functions.php";
include_once "../db_connect.php";
sec_session_start();
if(login_check($mysqli) === true) {
header('Location: ../index.php');
}
else
{
// Login form
}
Quite identical, apart from the file sources as the admin login.php
is located in /admin
. Despite this, the first one displays the login form correctly while the second redirects you to index.php
(even when in incognito, a mystery to me), causing a redirect loop (as index.php
sends it back for nog being logged in).
In addition to this, when I login with proper credentials, it does direct me to index.php
only to redirect me back to login.php
with error code 6
.
Please do comment if you want more information or code examples, I feel lost in my own project right now.
Any help is appreciated, Thank you
UPDATE 17 dec:
After a few hours of debug, we've concluded that the issue is not with the code but with the server configuration. A simple example:
<?php
session_start();
echo session_id();
?>
If you open this file on the production server, and refresh the page, it displays a new session id with every request. I currently have no clue why. I have confirmed the session file is created as well as the cookie. It contains the proper information and can be accessed by SSH with server permissions. Truly some strange behavior.
Any clues?