【发布时间】:2014-09-07 02:15:00
【问题描述】:
我有一个基于会话的带有验证码的帖子表单,例如代码知道是 Ujkd9 在刷新代码后变为 Hi8P4 。 这就是问题所在。如果有人发布表单输入的验证码变旧,如何获取旧会话?
【问题讨论】:
我有一个基于会话的带有验证码的帖子表单,例如代码知道是 Ujkd9 在刷新代码后变为 Hi8P4 。 这就是问题所在。如果有人发布表单输入的验证码变旧,如何获取旧会话?
【问题讨论】:
您不能,但您可以将旧会话保存到另一个会话密钥中,创建该会话的副本,例如:
$_SESSION['session_copy'] = $_SESSION['current'];
【讨论】:
我假设您的验证码是即时制作的,并通过 PHP 中的一些图像制作输出。您的问题是,一旦您制作了图像并输出它,您就无法弄清楚 CAPTCHA 值实际上是什么?
由于我完全不知道您的应用程序结构或数据库是什么样的,因此我可以根据我的工作向您提供建议:
如果我可以假设您的 PHP 脚本看起来像这样:
$captcha_string = make_hash(); // This function could just be the consolidation of your step in making the hash. I don't know, so it's going to be generic.
make_captcha_image($captcha_string); // Again, I don't know exactly how this goes, so I have to assume.
用外行的话来说,您需要将它存储在某个地方。但是哪里?现在,我想记住,我从来没有特别直接与 Captcha 合作过,所以我不是 100% 知道“最佳实践”是什么,我也不知道你在做什么,所以这些对于一个模糊的问题,可能会是模糊的答案。在我看来,大概有 3 个选项。
实际上,我可能会首先使用数据库。在我的数据库中,我将有一个名为 captcha 的表,其定义如下:
CREATE TABLE captcha (captcha_id int unique not null auto_increment, session_id VARCHAR(100) NOT NULL, captcha_string VARCHAR(6) NOT NULL)
注意: 我不知道session_id() 函数会返回多长,我目前无法检查。如果您知道会话 ID 的长度,请更改 session_id 上的长度以匹配。同样对于captcha_string,我不知道您的验证码会有多少个字母。更改定义以适合您的用途。
你要做的,用一句话来说是:
$captcha_data
请注意,对于这个示例,我假设您的数据库连接,无论它是什么类型,都位于一个名为 $db 的对象中,我没有使用特定类型的数据库,只是我在自己的数据库类中使用的方法。您的定义看起来很相似,但可能并不准确。
$session_id = session_id();
$sql = "SELECT * FROM captcha WHERE session_id='".mysqli_real_escape_string($session_id)."'";
$result = $db->query($sql);
if($result!==false){
$captcha_data = $db->fetchrow($result);
}
$db->free_result($result);
$captcha_string = (isset($captcha_data['captcha_string'])) ? $captcha_data['captcha_string'] : make_hash(); // This function could just be the consolidation of your step in making the hash. I don't know, so it's going to be generic.
if(!isset($captcha_data['captcha_id'])){
$sql = "INSERT INTO captcha (session_id, captcha_string) VALUES('".mysqli_real_escape_string($session_id)."','".mysqli_real_escape_string($captcha_string)."')";
$db->query($sql);//You should check that this query is successful in your code, but for brevity I am skipping it.
}
make_captcha_image($captcha_string); // Again, I don't know exactly how this goes, so I have to assume.
现在请记住,我可能会在验证码数据中添加一个日期或时间列,这样我就可以从几个月内未使用的帐户中删除值,只是为了缩小规模,但这是我留下的给你。
我不能说我推荐这个选项。它实际上与我之前的答案相同,只是没有数据库交互。
换句话说,我们正在做以下事情:
$_SESSION['captcha_id'] 值,如果是,则使用它。如果没有,请创建它。这段代码看起来很奇怪,所以我建议查一下Ternary Operators
//Assuming your session_start() is at the top of the page
$captcha_id = $_SESSION['captcha_id'] = (isset($_SESSION['captcha_id'])) ? $_SESSION['captcha_id'] : make_hash();
make_captcha_image($captcha_string);
我想说,如果这是您选择的选项,那么您需要做出一些人生决定。这不应该被使用。曾经。认真的。
话虽如此,这里的基本前提是
代码中的样子:
$session_id = session_id();
if(file_exists('temp/'.$session_id.'.php')){
$captcha_string = $captcha_data = file_get_contents('temp/'.$session_id.'.php');
}else{
$captcha_string = hash();
file_put_contents('temp/'.$session_id.'.php',$captcha_string);
}
make_captcha_image($captcha_string);
只是重申:不要使用这种方法。我提供这个答案只是因为你的问题是问如何防止验证码改变。
【讨论】: