我创建了一个递归文档,它基本上作为两个不同的页面(首先输入ID然后输入密码),以保护或更好地隐藏最终目的地的URL。
在实现了一个功能以防止同一用户的多个活动会话后,我开始收到警告,这可以在页面重定向之前在下图中看到。我知道这些警告意味着什么,以及它们为什么会引起。警告是第40,41,80和81行的session_start()
和session_regenerate_id()
的结果。
然而,奇怪的是,如果我不包含session_start()
和session_regenerate_id()
,则页面永远不会重定向或重定向到自身,因为$_SESSION["session"]
永远不会被设置。
所有这一切都归因于我摧毁任何其他会话的方式。我找到了方法here。我甚至不确定这是否是终止特定会话的正确方法,但它似乎有效(尽管它最终导致导致警告的逻辑)。
我想知道如何在实现相同的最终结果但不将逻辑拆分成多个页面时避免或解决这些警告?
任何见解都将不胜感激。
以下是实际代码。
<?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>