我正在制作一个表单,我想使提交的PHP页面只有在提交表单时才能访问,防止自定义请求到我的PHP页面。
这是我的form.html:
<html>
<head>
<title>Name/Surname form</title>
</head>
<body>
<form id="form1" method="POST" action="processData.php">
Name: <input type="text" id="name" name="name"><br>
Surname: <input type="text" id="surname" name="surname"><br>
<input type="submit" value="Submit form">
</form>
</body>
</html>
然后是我的processData.php:
<?php
if(!isset($_POST['name'],$_POST['surname'])) die;
include ("config.php");
//connect
$mysqli = new mysqli($dbhost, $dbuser, $dbpassword, $dbname); //variables from config.php
//check connection
if (mysqli_connect_errno()) {
printf("Connect failed: %sn", mysqli_connect_error());
exit();
}
if ($stmt = $mysqli->prepare("INSERT INTO name_surname_table (name, surname) values (?, ?)")) {
//bind
$stmt->bind_param('ss', $name, $surname);
//set
$name=$_POST['name'];
$surname=$_POST['surname'];
//execute
$stmt->execute();
//close
$stmt->close();
}
else {
//error
printf("Prepared Statement Error: %sn", $mysqli->error);
}
?>
问题是,如果我做一个自定义的帖子请求没有提交表单在我的前一页,数据提交给数据库,这意味着一个自动化的程序可以只是把它想要的任何东西在我的数据库…我该如何预防呢?
谢谢!
你有很多选项来阻止机器人自动提交你的表单:
-
使用验证码或一些简单的计算字段(例如
What gives 3 + 2 ?
) -
带有令牌
-
用$_REQUEST变量做一些检查
一个令牌可以这样做:
session_start();
//generate a unique string
$token = uniqid(rand(), true);
//Store the token
$_SESSION['token'] = $token;
//Store the token_time
$_SESSION['token_time'] = time();
添加一个隐藏的输入到你的表单:
<input type="hidden" name="token" id="token" value="<?php echo $token;?>"/>
然后在将表单提交给数据库之前:
session_start();
//If token exists
if(isset($_SESSION['token']) && isset($_SESSION['token_time']) && isset($_POST['token']))
{
//If it's the same as the posted one
if($_SESSION['token'] == $_POST['token'])
{
//For example 15 mins ago
$old_time = time() - (15*60);
//If token hasn't expired
if($_SESSION['token_time'] >= $old_time)
{
//Do your queries here
}
}
}
基本上,您无法阻止恶意客户端向您的服务器发送"不正确"的数据。这是由你来检测这种情况,并适当地处理错误情况。
如果只有某些用户能够提交数据,那么显然您需要某种形式的登录系统。然后,您可以信任来自登录用户的任何数据,并拒绝其他所有数据。
如果您只是想知道客户端在前一页加载了表单,您可以添加一个包含"nonce"的隐藏字段-一个随机字符串,其值存储在服务器上的某个地方,例如PHP会话中。如果提交的nonce与期望值不匹配,则拒绝输入。注意,不能保证用户在浏览器中与表单交互,只能保证用户下载了表单(因为程序仍然可以提取nonce并激发提交表单)
表单中可以有一个隐藏字段,其中包含过期的秘密代码…
当您生成表单时,您通过在时间上运行哈希来计算代码,甚至只是选择一个随机数。然后将其存储在会话中,并将其插入到您发送的表单中。
在处理表单提交时,检查以确保秘密代码与存储在会话中的代码相同。
您应该为表单创建一个基于令牌的身份验证。
在显示表单的页面中,首先使用随机代码设置会话变量。
//generate this using whatever random code generation method you prefer.
$_SESSION["token"] = "your-random-code";
在您的论坛中设置如下隐藏字段
<input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>">
在提交处理程序php文件中,执行如下检查:
if(isset($_POST['token']) && $_POST['token'] == $_SESSION['token'])