I'm working on a simple app for internal use for a small company. I am having difficulties getting the account logins working correctly, and I believe it has something to do with $_SESSION not being set like I expected it to. Now I am fairly new to PHP, and have been learning as I go.
index.php contains this:
<?php
session_start();
require_once('includes/config.inc.php');
require_once('includes/functions.inc.php');
// Check login status -- if not logged in, redirect to login screen
if (check_login_status() == false) {
redirect('login.php');
}
So when I load the app, I'm redirected to login.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1- strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html;charset=utf-8" />
<title>Login Page</title>
<link rel="stylesheet" type="text/css" href="css/login.css" />
</head>
<body>
<form id="login-form" method="post" action="includes/login.inc.php">
<fieldset>
<legend>Login to Inventory System</legend>
<p>Please enter your username and password to access the Inventory system</p>
<label for="username">
<input type="text" name="username" id="username" />Username:
</label>
<label for="password">
<input type="password" name="password" id="password" />Password:
</label>
<label>
<input type="submit" name="submit" id="submit" value="Login" />
</label>
</fieldset>
</form>
</body>
</html>
When I hit submit on the login page, includes/login.inc.php is called:
<?php
session_start();
require_once('config.inc.php');
require_once('functions.inc.php');
// Escape any unsafe characters before querying database
$username = $con->real_escape_string($_POST['username']);
$password = $con->real_escape_string($_POST['password']);
// Construct SQL statement for query & execute
$query = "SELECT * FROM users WHERE username = '" . $username . "' AND password = '" . MD5 ($password) . "'";
$result = mysqli_query($con,$query) or die(mysqli_error($con));
// If one row is returned, username and password are valid
if (is_object($result) && $result->num_rows == 1) {
$_SESSION['logged_in'] = true;
redirect('../index.php');
} else {
redirect('../login.php');
}
?>
Now I've been able to determine that the login is being processed successfully, because if I disable the check_login_status function in index.php, I'm redirected to index.php if I login with a valid account. Under the same conditions, an incorrect password will reload login.php. With the function disabled, I've also tried adding "print_r($_SESSION)" at the top of index.php, but nothing ever loads, which makes me think something is wrong with my function.
functions.inc.php:
<?php
function redirect($page) {
header('Location: ' . $page);
exit();
}
function check_login_status() {
// IF $_SESSION['logged_in'] is set, return the status
if (isset($_SESSION['logged_in'])) {
return $_SESSION['logged_in'];
}
return false;
}
?>
config.inc.php:
<?php
$con=mysqli_connect("server_name","user","pass","db_name");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
?>
I'm really at a loss, and I don't know where the problem is. I've checked for syntax errors with "php -l file.php" and found no syntax errors. I'm not sure how to do any other debugging with this, or what I'm missing. Help is truly appreciated!
Code blocks might be off a little. Yes, I know MD5 passwords are not recommended, and that will be changed to use salt once I can get functionality in my app. I will also be escaping/preparing all MySQL queries once I get the login piece working.
It seems to me like in your function you've put return false;
which is meaning your function always returns false. That might be why you can't see anything when you print $_SESSION. I would encase that "return false" in an else, like this:
function check_login_status() {
// IF $_SESSION['logged_in'] is set, return the status
if (isset($_SESSION['logged_in'])) {
return $_SESSION['logged_in'];
}
else {
return false;
}
}
Also, I would consider setting the user ID in the $_SESSION variable instead of just setting it as a boolean. Means you can create user-related content more easily by just setting $i = $_SESSION['id'];
in your include at the beginning.
this won't fix your problem, but simplifies your check_login_status function.
function check_login_status() {
return (isset($_SESSION['logged_in']) && $_SESSION['logged_in']===true);
}
also your session variable is not being set because the cookie is not being stored by the browser. your header() function overrides the other headers that would've been set.
Many people use session_write_close(); as the fix. Add that BEFORE the redirect.
See: https://bugs.php.net/bug.php?id=14636
<?php
session_start();
require_once('config.inc.php');
require_once('functions.inc.php');
// Escape any unsafe characters before querying database
$username = $con->real_escape_string($_POST['username']);
$password = $con->real_escape_string($_POST['password']);
// Construct SQL statement for query & execute
$query = "SELECT * FROM users WHERE username = '" . $username . "' AND password = '" . MD5 ($password) . "'";
$result = mysqli_query($con,$query) or die(mysqli_error($con));
// If one row is returned, username and password are valid
if (is_object($result) && $result->num_rows == 1) {
$_SESSION['logged_in'] = true;
session_write_close();
redirect('../index.php');
} else {
redirect('../login.php');
}
?>