尝试抛弃验证码之道

本文介绍了一种替代验证码的方法,利用Ajax与PHP结合产生及验证令牌,以防止自动化程序提交垃圾信息,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        验证码作为防止表单垃圾信息普遍采用的方法,一直被广泛使用。但是同时它造成了很不好的用户体验,为合法用户的正常操作带来不便。本文介绍了一种抛弃使用验证码的方法,来防止自动程序进行垃圾信息的提交。
         以前见过类似的方法,这几天在中文版的《15天学会jQuery》上看到了原作者有关的链接(http://15daysofjquery.com/examples/contact-forms/),简单试验了一下效果不错。首先说明一下整体流程,主要对原文总述部分进行了简单翻译:
1) 当表单被载入后,我们创建一个到PHP 文件的Ajax 调用;
2) 该PHP 文件将取得当前时间(依靠服务器,并不是访问者的浏览器);
3) 该PHP 文件将结合时间戳, 加上一个加密的字 (用户自定义的一个字符串— —译者注),产生一个32位的“哈希”并把它作为Cookie存储到访问者的浏览器上;
4) jQuery将接收这个从Ajax 调用来的时间戳信息,并将该哈希值或“令牌”作为表单的隐藏标签而存储;
5) 当该表单为处理而被发送,这个时间戳的值(表单中的— —译者注)将和存储在Cookie中的32位字符“令牌”做比较;
6) 如果信息不匹配,或是丢失,又或者时间戳过期,我们将终止表单处理的执行,同时这个垃圾邮件发送者将会把目标转移到另一个简单的猎物上(放弃我们这个目标— —译者注)。
通过上面的介绍,相信大家已经基本明白了吧。核心部分就是在页面被载入时,采用 Ajax 动态创建一个特定的隐藏表单元素,该元素只有在真正用户访问时才会存在,对于自动化的“机器人”来说是不存在的。好了,下面我们来动手做个简单的例子实践一下:
这里需要 3 个文件:前端提交表单的页面 test.html,提交后的后端处理页面test.php,以及用户产生“令牌”的Ajax 页面do.php。(没错,前两个页面也可合并为一个)首先当然是创建表单了:

<form method="post" name="form1" action="test.php">
<label>请输入内容:<input type="text" name="message" /></label>
<label><input type="submit" name="submit" /></label>
</form>

接下来用 JavaScript 实现 Ajax,在页面加载完毕后从 do.php 获取“令牌” (这里使用jQuery的方法):

<script type="text/javascript">
$().ready(function(){
$.get("do.php", function(txt){
$("form[name=form1]")
.append('<input type="hidden" name="ts" value="' + txt + '">');
})
});
</script>

“令牌”是怎么产生的呢?当然是从do.php中来的啦:

<?php
//PHP5.1 后可用$_SERVER['REQUEST_TIME']代替 time(),更高效
$now = $_SERVER['REQUEST_TIME'];
//把时间戳与自定义字符串(我这里用的“linvo” )拼接后进行哈希,并存入 cookie
//参数 0 说明该cookie随浏览器关闭而失效
setcookie('token', md5('linvo'.$now), 0);
echo $now;
?>

下面开始验证吧:

<?php
$seconds = 60 * 10; //有效时间
if(!isset($_POST['ts']) || empty($_POST['ts'])) {
die('你是机器人吧');
}
if(!isset($_COOKIE['token'])) {
die('父令牌丢失');
}
if(intval($_POST['ts']) + $seconds < $_SERVER['REQUEST_TIME']) {
die('令牌已失效');
}
if(md5('linvo'.$_POST['ts']) != $_COOKIE['token']) {
die('令牌错误');
}
echo '提交成功!<br />';
echo '你提交的消息是:'.$_POST['message'];
?>

到这里,已经基本实现了防止自动化程序提交的功能。再完善一点的话,在产生“令牌”时可以加上防止缓存的代码,如:

header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值