I have created a recursive document, which basically acts as two different pages (first enter ID and then enter password), in order to protect or better hide the URL of the ultimate destination.
After having implemented a function to prevent multiple active sessions for the same user I began receiving warnings, which can be seen in the image below, before the page redirects. I know what the warnings mean and why they're caused. The warnings are a result of session_start()
and session_regenerate_id()
on lines 40, 41, 80, and 81.
Strangely, however, if I don't include session_start()
and session_regenerate_id()
the page never redirects or rather redirects to itself again since $_SESSION["session"]
never ends up being set.
All of this is due to the way I'm destroying any additional session(s). I found the method here. I'm not even sure if this is the correct way to terminate a particular session, but it seems to work (although it's ultimately responsible for the logic which causes warnings).
I'm wondering how I can avoid or address these warnings while achieving the same end result but without splitting the logic into multiple pages??
Any insights would be appreciated.
Below is the actual code.
<?php
session_start();
// isset($_SESSION["session"]) && !empty($_SESSION["session"])
if ($_SESSION["session"]) {
echo "<script type='text/javascript'> location.href = 'showcase.php' </script>";
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
// enter password or set password
if (isset($_POST["password"]) && empty($_POST["password"])) {
$error = "A password is required.";
$identity = "password";
$tip = "Password";
$prompt = "Enter Password";
} else if (isset($_POST["password"]) && !empty($_POST["password"])) {
include "inc/dat/connect.php";
if ($_SESSION["promptPersist"] === "Enter Password") {
// compare password
$sql = "SELECT prim, pass, sess FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if (password_verify($_POST["password"], $result["pass"])) {
unset($_SESSION["promptPersist"]);
$idPersist = $_SESSION["idPersist"];
// deactivate any other session of same user
$sql = "SELECT sess FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
session_id($result["sess"]);
session_start();
session_unset();
session_destroy();
// start new session; set pass and sess
session_start();
session_regenerate_id(); // for safe keeping
$_SESSION["idPersist"] = $idPersist;
unset($idPersist);
$sql = "UPDATE users SET sess = :session WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->bindParam(":session", session_id());
$stmt->execute();
// set session variable to establish persistent session
$sql = "SELECT prim FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION["session"] = $result["prim"];
echo "<script type='text/javascript'> location.href = 'showcase.php' </script>";
} else {
$error = "Password is incorrect.";
$identity = "password";
$tip = "Password";
$prompt = "Enter Password";
}
} else if ($_SESSION["promptPersist"] === "Set Password") {
unset($_SESSION["promptPersist"]);
$idPersist = $_SESSION["idPersist"];
// deactivate any other session of same user
$sql = "SELECT sess FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
session_id($result["sess"]);
session_start();
session_unset();
session_destroy();
// start new session; set pass and sess
session_start();
session_regenerate_id(); // for safe keeping
$_SESSION["idPersist"] = $idPersist;
unset($idPersist);
$sql = "UPDATE users SET pass = :password, sess = :session WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->bindParam(":password", password_hash($_POST["password"], PASSWORD_DEFAULT));
$stmt->bindParam(":session", session_id());
$stmt->execute();
// set session variable to establish persistent session
$sql = "SELECT prim FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $_SESSION["idPersist"]);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION["session"] = $result["prim"];
echo "<script type='text/javascript'> location.href = 'showcase.php' </script>";
}
$conn = null;
}
// enter id
if (!isset($_POST["password"]) && empty($_POST["id"])) {
$error = "An ID is required.";
} else if (!isset($_POST["password"]) && !empty($_POST["id"])) {
include "inc/dat/connect.php";
$id = trim($_POST["id"]);
$id = stripslashes($_POST["id"]);
$id = htmlspecialchars($_POST["id"]);
$sql = "SELECT usrn, pass FROM users WHERE usrn = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":id", $id);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result) {
$error = "";
$identity = "password";
$tip = "Password";
$_SESSION["idPersist"] = $id;
if (is_null($result["pass"])) {
$prompt = "Set Password";
$_SESSION["promptPersist"] = "Set Password";
} else {
$prompt = "Enter Password";
$_SESSION["promptPersist"] = "Enter Password";
}
} else {
$error = strtoupper($_POST["id"])." does not exist.";
}
$conn = null;
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<link href="css/index.css" rel="stylesheet">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>joli</title>
</head>
<body>
<form
accept-charset ="UTF-8"
action ="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>"
enctype ="application/x-www-form-urlencoded"
method ="post">
<div id="error">
<?php echo $error; ?>
</div>
<div class="strict">
<input
id ="<?php echo (empty($identity)) ? "id" : $identity; ?>"
name ="<?php echo (empty($identity)) ? "id" : $identity; ?>"
size ="25"
title ="<?php echo (empty($tip)) ? "ID" : $tip; ?>"
type ="text"
>
<input
id ="submit"
name ="submit"
type ="submit"
value ="<?php echo (empty($prompt)) ? "Enter ID" : $prompt; ?>"
>
</div>
</form>
<script type="text/javascript" src="jas/index.js"></script>
</body>
</html>