我正在关注this tutorial以尝试制作PHP表单密钥验证脚本。出于某种原因,我的构造函数没有为我的$old_formKey
变量创建值。
该教程提到单身人士更安全,但不会进入实施阶段。我知道使用Java的OOP的基本原则,但我对PHP OOP原则知之甚少。我只是试图通过使类变量静态来实现它 - 我认为这就是我的问题所在。但是,当我的构造函数被调用时,它应该给$old_formKey
$_POST[form_key]
的值,如果是isset()“
我无法让构造函数将旧formKey的值放在所需的变量空间中。
所以这就是我遇到问题的地方。
<?php
class formKey
{
private static $formKey;
private static $old_formKey;
public function validate()
{
echo $_POST['form_key'];
//We use the old formKey and not the new generated version
if($_POST['form_key'] == $old_formKey) {
//The key is valid, return true.
return true;
}
else {
//The key is invalid, return false.
return false;
}
}
}
?>
我的formKey验证脚本看起来像这样。
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
//Validate the form key
if(!isset($_POST['form_key']) || !$formKey->validate()) {
//Form key is invalid, show an error
$error_msg = 'Security Error.';
$die = "die";
}
else {
/*continue validation*/
}
}
?>
该脚本返回错误消息,然后显示它,因为$old_formKey
方法中的validate()
永远不会给出值。
出于某种原因,我无法在validate()
方法中修改类变量。对不起,如果之前已经解决过。我老实地看着,找不到它!
function __construct()
{
//We need the previous key so we store it
if(isset($_SESSION['form_key']))
{
self::$old_formKey = $_SESSION['form_key'];
}
}
抱歉,我忘了包含我的构造函数。它已在上面添加。
答案 0 :(得分:1)
扩展formKey类?
class B extend formKey{
public function validate($formKey, $oldFormKey)
{
return $formKey == $oldFormKey;
}
}
像这样称呼它
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$oldFormKey = "abc";
$formKey = new B();
if (!isset($_POST['form_key'])
|| !$formKey->validate($_POST['form_key'], $oldFormKey)) {
//Form key is invalid, show an error
$error_msg = 'Security Error.';
$die = "die";
} else {
//continue validation
}
}
它可能对您有用,而且,我很好奇&#34;出于某种原因,我无法在validate()方法中修改类变量&#34;
答案 1 :(得分:1)
要使变量通过对象(__construct()
到validate()
),您需要在类范围内分配它们,然后从同一范围内调用它们:
class formKey
{
private $formKey,
$old_formKey;
public function __construct()
{
// I just set to false as default
$this->old_formKey = false;
// Assign here
if(isset($_SESSION['form_key']))
$this->old_formKey = $_SESSION['form_key'];
}
public function validate()
{
// Use $this-> to recall it from the construct
return ($_POST['form_key'] == $this->old_formKey);
}
}
答案 2 :(得分:0)
正如我已经写过评论,你提到的像 Dagon 所写的教程已经过时了,其次是完全虚假。
这与验证表单无关,关注此主题识别表单。
您生成一个由服务器生成的唯一标识符键(本例为PHP),以便跟踪表单状态。如果唯一的密钥发生变化,与服务器存储的密钥不同,则表单可能会在无法识别的情况下被拒绝(这并不意味着所有表格不有效)。
本教程使用面向对象的方法,所以我会尊重它。正在制定以下步骤
users
)SESSION
确定提交时的表单,并将(未识别的)密钥与存储在SESSION
<中的(已识别的)密钥进行比较/ p>
4.1。在满足身份时验证表单
4.2。如果无法识别,则拒绝表格
从生成实例开始,类的布局非常简单,它不需要是singleton,也不应该包含任何静态。
该类的基础可以分为三个部分,创建,存储和识别。
class FormIdentifier {
const CONTAINER_KEYSPACE = 'form_keys';
/**
* Generate a key
* @return string
*/
public function generateKey() {
// you can use any complicated mumbo-jumbo to generate a key instead
$key = uniqid();
// store it
$this->storeKey($key);
// return for use, e.g. in a form
return $key;
}
/**
* Store a key into users session
*/
protected function storeKey($key) {
session_start();
$_SESSION[self::CONTAINER_KEYSPACE][] = $key;
session_write_close();
}
/**
* Identifies a key against the keys in the users stored session.
* @return true if identified, false otherwise
*/
public function identifyKey($key) {
session_start();
if( ($found = search_array($key, $_SESSION[self::CONTAINER_KEYSPACE])) !== false ) {
unset($_SESSION[self::CONTAINER_KEYSPACE][$found]);
session_write_close();
return true;
}
session_write_close();
return false;
}
}
要生成密钥,我们不会将HTML输出与类和方法混合使用。 FormIdentifier
的目的只是创建,存储和标识表单键,没有别的。这是一个在表单中使用的示例
<form>
<input type="hidden" name="form_key" value="<?php (new FormIdentifier)->generateKey() ?>" />
</form>
您也可以将返回的密钥存储在某处,并以不同的方式使用它,无论您需要什么样的套件。
<?php $key = (new FormIdentifier)->generateKey(); ?>
<input type="hidden" name="form_key" value="<?= $key ?>" />
要识别(并最终验证)表单,您可以指定发布的表单 key ,并将其与存储在用户会话中的密钥进行比较。此处使用的结构最有可能向用户显示密钥不匹配的一些通知。它完全取决于您希望如何实现此步骤,您可以将其包装在函数中,甚至可以将其与类FormIdentifier
结合使用。
/**
* Simple if/else, a POST was made so act on `form_key`s presence only
*/
if($_POST && array_key_exists('form_key', $_POST)) {
if((new FormIdentifier)->identifyKey($_POST['form_key')) {
// identity was verified
// validate your form
$fv = new FormValidator($_POST);
// or whatever ..
$fv->validate();
}
else {
// unable to determine identity
// do something silly ..
}
}
一些注释