I have a question about sessions. I noticed something unusual when I was testing my PHP code. Basically, I have two courses and the credentials are stored in their own database.
- Example: Course 1: Username: abc Password: 123, database table: flitpc
- Example: Course 2: Username: abc Password: 999, database table: itst
So the code below determines the login for the respective courses (both exactly same code for each course with the difference being the database table)
<?php // Initialize the session session_start(); // Check if the user is already logged in, if yes then redirect him to welcome page if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){ header("location: index"); exit; } // Include config file require_once "config.php"; // Define variables and initialize with empty values $username = $password = ""; $username_err = $password_err = ""; // Processing form data when form is submitted if($_SERVER["REQUEST_METHOD"] == "POST"){ // Check if username is empty if(empty(trim($_POST["username"]))){ $username_err = "Please enter username"; } else{ $username = trim($_POST["username"]); } // Check if password is empty if(empty(trim($_POST["password"]))){ $password_err = "Please enter your password"; } else{ $password = trim($_POST["password"]); } // Validate credentials if(empty($username_err) && empty($password_err)){ // Prepare a select statement $sql = "SELECT id, username, password FROM flitpcusers WHERE username = ?"; if($stmt = mysqli_prepare($link, $sql)){ // Bind variables to the prepared statement as parameters mysqli_stmt_bind_param($stmt, "s", $param_username); // Set parameters $param_username = $username; // Attempt to execute the prepared statement if(mysqli_stmt_execute($stmt)){ // Store result mysqli_stmt_store_result($stmt); // Check if username exists, if yes then verify password if(mysqli_stmt_num_rows($stmt) == 1){ // Bind result variables mysqli_stmt_bind_result($stmt, $id, $username, $hashed_password); if(mysqli_stmt_fetch($stmt)){ if(password_verify($password, $hashed_password)){ // Password is correct, so start a new session session_start(); // Store data in session variables $_SESSION["loggedin"] = true; $_SESSION["id"] = $id; $_SESSION["username"] = $username; // Redirect user to welcome page header("location: index.php"); } else{ // Display an error message if password is not valid $password_err = "The password you entered was not valid"; } } } else{ // Display an error message if username doesn't exist $username_err = "No account found with that username"; } } else{ echo "Oops! Something went wrong. Please try again later."; } // Close statement mysqli_stmt_close($stmt); } } // Close connection mysqli_close($link); } ?>
So here is the thing, I have both tabs open on my browser, 1 for course 1, other for course 2.
Defect
Tab 1: I log into course 1 with its credentials, works fine, I don’t log out.
Tab 2: I log into course 2 with course 2 username (same username as course 1), but I also use course 1 password, it logs me in,
Now if I log out of both courses and try the second bullet point above again, I can’t log in.
So it’s unusual and I want to know how to fix this and understand a little bit more about sessions as I think it’s related to that.
Update
I have also found out it doesn’t matter if usernames are different. It may be recognising the same password used for both login.
Advertisement
Answer
Authentication is never actually performed in tab 2. Because you already have a session you’re redirected to the index when you hit this code block:
// Check if the user is already logged in, if yes then redirect him to welcome page if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){ header("location: index"); exit; }
You need to save course
somewhere in $_SESSION
and check if an appropriate session not only exists but matches the course, otherwise authentication using table 1 credentials is indistinguishable from authentication using table 2 credentials.
EDIT:
After authentication save from where the authentication occurred:
// Store data in session variables $_SESSION["loggedin"] = true; $_SESSION["id"] = $id; $_SESSION["username"] = $username; $_SESSION["authenticated_from"] = "flitpcusers";
Then when you’re checking if a $_SESSION exists also check if it’s for the appropriate course, so:
// Check if the user is already logged in, if yes then redirect him to welcome page if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true && $_SESSION["authenticated_from"]==="flitpcusers"){ header("location: index"); exit; }
This will prevent a table 1 authenticated session as being recognized as a table 2 session.
While the above will fix the strange behaviors you’re observing I’d really look at redesigning your database scheme here. It’s strange that I need to authenticate differently for different courses. Ideally I authenticate once and that authentication is used for any/all services under that identity. Look at Google: I don’t have to login to Youtube then login to Gmail then login to Search, I log in once and then Google servers determine which services I have access to.