我在下面有这个查询:
// They have a token and estimate id
if (isset($_GET['estimate_token']) && isset($_GET['estimate_id']))
{
if ($select = $db -> prepare("SELECT estimate_id FROM estimates WHERE estimate_token =?"))
{
$select -> bind_param('s', $_GET['estimate_token']);
$select -> execute();
$select -> store_result();
$select -> bind_result($estimate_id);
$select -> fetch();
if ($select -> num_rows == '0')
{
header ("Location: ./login.php");
}else{
}
$select -> close();
}
}
通过电子邮件向客户提供带有令牌的链接以及来自数据库的估计ID。当他们点击链接时,它会将它们带到正确的估计值。我遇到的问题是,如果客户手动用网址中的任何数字替换estimate_id或estimate_token,它仍然会让你在网站上将你踢到login.php。这很糟糕,因为它允许客户查看系统中的其他估计值。
我认为问题在于$select -> num_rows
抛出误报。
答案 0 :(得分:1)
您的逻辑无效 - 您必须查找token
和id
等于$_GET
值的记录,因此您需要使用以下查询:
$SELECT estimate_id FROM estimates WHERE estimate_token =? AND estimate_id = ?
这将只选择一条特定记录。
完整代码类似于:
if ($select = $db -> prepare("SELECT estimate_id FROM estimates WHERE estimate_token = ? and estimate_id = ?"))
{
// supposing id is `int`
$select -> bind_param('si', $_GET['estimate_token'], $_GET['estimate_id']);
$select -> execute();
$select -> store_result();
// if you need to know just if row exists
// there's no need for this two lines
//$select -> bind_result($estimate_id);
//$select -> fetch();
if ($select -> num_rows == 0)
{
header ("Location: ./login.php");
} else {
}
$select -> close();
}
答案 1 :(得分:0)
如果他们没有令牌,你不应该立即将他们踢出去吗?我认为这可能是问题所在。或者,按照您编写的方式,如果他们没有令牌和估算ID,您就不会有ELSE。您唯一的ELSE语句位于数据库选择代码中。
答案 2 :(得分:0)
这似乎更合理的逻辑,这将确保他们在提交no或空白令牌/ ID时被拒绝登录。如果您需要进行任何进一步的验证,它也将覆盖您,因为如果您需要将它们丢弃,您只需设置1个bool即可。
由于您未使用数据库中的结果,因此将其更改为数据库端计数可能会稍快一些。
$needsLogin = true;
if (!empty($_GET['estimate_token']) && !empty($_GET['estimate_id']))
{
$select = $db->prepare('SELECT COUNT(1) FROM estimates WHERE estimate_token = ? AND estimate_id = ?');
$select->bind_params('si', $_GET['estimate_token'], $_GET['estimate_id']);
$select->execute();
$select->bind_result($cnt);
$select->fetch();
if ($cnt > 0) {
$needsLogin = false;
}
$select->close();
}
if ($needsLogin) {
header('Location: ./login.php');
die();
}
PS。 PDO将使您的数据库代码更好地处理:
$select = $db->prepare('SELECT COUNT(1) FROM estimates WHERE estimate_token = ? AND estimate_id = ?');
$select->execute(array($_GET['estimate_token'], $_GET['estimate_id']));
$cnt = $select->fetchColumn();
if ($cnt > 0) {
$needsLogin = false;
}