我已经用谷歌搜索了很多,但仍然没有答案,所以我决定在这里问这个问题: PHP 有没有办法检查我在某些脚本中收到的数据是否来自页面上的特定表单?我这样问是因为每个人都可以看到我用于将数据保存到数据库的脚本的名称,所以如果有人能够找到整个 URL,他也能够向脚本发送一些虚假数据,我需要一个条件,即仅当数据来 self 的页面上的正确表单时才会触发保存过程。
我使用 jQuery 来调用 AJAX 函数,所以基本上如果我单击“发送”按钮,就会触发 $.POST() 方法来调用脚本来保存数据。
谢谢, 托马斯
最佳答案
使用 token 检查请求是否有效
您始终可以在提交数据时添加某种安全 token :
token 可以轻松扩展用于许多不同的用途,并且在检查某些请求是否有效时覆盖广泛的区域,例如您可以让您的非关键表单向公众开放,要求用户从某个页面获取他们的 key (强制他们打开该页面),然后在提交数据时使用这些 key 来识别他们。
当然,所有这些对用户来说都是完全透明的,因为您可以通过 cookie(或 session cookie)从首页提供 key ,这在这里并不重要,没有或多或少的安全性,因为服务器 key 在使用后应该改变并在指定时间内或当用户身份发生变化时失效)。
在本使用示例中,只有打开首页的用户才能向服务器提交数据。
另一种情况是在包含向服务器提交数据的表单的同一页面上赠送 cookie。每个打开页面的用户都将拥有立即提交数据的 key ,但是如果有人尝试从外部发出请求,则会失败。
请参阅OWASP Cross Site Request Forgery
和 codinghorror.com Blog CSRF and You
仅使用 AJAX?
这是我对另一个问题的回答,这个答案涵盖了向ajax请求插入附加数据的不同方法:Liftweb: create a form that can be submitted both traditionally and with AJAX (仔细看看
$.ajax({
...
data: /* here */
...
目前我正在以这种方式使用 token :
用于提交的表单
此隐藏输入可以添加到表单中,这不是必需的,因为您可以使用前面描述的方法 at another answer 。
<input type="hidden" name="formid" value="<?php echo generateFormId(); ?>" />
函数generateFormId()
简单地生成随机字符串并将其保存到 session 存储中
function generateFormId() {
// Insert some random string: base64_encode is not really needed here
$_SESSION['FORM_ID'] = 'FormID'.base64_encode( uniqid() );
// If you want longer random string mixed with some other method just add them:
//$_SESSION['FORM_ID'] = 'FormID'.base64_encode( crypt(uniqid()).uniqid('',true) );
return $_SESSION['FORM_ID'];
}
处理提交的表单数据
if (!isset($_SESSION['FORM_ID']) || $_SESSION['FORM_ID'] != $_POST['formid']) {
// You can use these if you want to redirect user back to form, preserving values:
//$_SESSION['RELOAD_POST'] = $_POST;
//$_SESSION['RELOAD_ID'] = uniqid('re');
echo 'Form expired, cannot submit values.';
//echo '<a href="form.php?reload='.$_SESSION['RELOAD_ID'].'">Go back and try again</a>';
exit(1); // <== Stop processing in case of error.
}
如果需要检查哪个表单正在提交数据
然后您可以在生成 id 时添加前缀,并在处理表单数据时检查该前缀。
这是一个 php 脚本处理多种不同表单的情况。
请记住,防止邪恶用户的唯一最终答案是拔掉服务器上的所有电线...
关于php - 来自精确表格的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10469895/