抛弃验证码–照样可以拒绝机器人

本blog文章如没特殊声明均为原创文章,转载请注明出处,谢谢!

check
看到上面之类的验证码,估计很多人的评论欲望都没有了吧,这里还有更多呢!都是超级变态型的!

验证码作为防止表单垃圾信息普遍采用的方法,一直被广泛使用。但是同时它造成了很不好的用户体验,为合法用户的正常操作带来不便。本文介绍了一种抛弃使用验证码的方法,来防止自动程序进行垃圾信息的提交。
原文链接:(http://15daysofjquery.com/examples/contact-forms/),简单试验了一下效果不错。

原理:
核心部分就是在页面被载入时,采用AJAX动态创建一个特定的隐藏表单元素(姑且叫令牌吧),该元素只有在真正用户访问时才会存在,对于自动化的“机器人”来说是不存在的。通过客户端提交的隐藏表单的令牌和服务器端的对比来验证是否机器人。

1、当表单被载入后,我们创建一个到PHP文件的AJAX调用;
2、该PHP文件将取得当前时间(依靠服务器,并不是访问者的浏览器);
3、该PHP文件将结合时间戳,加上一个加密的字(用户自定义的一个字符串——译者注),产生一个32位的“哈希”并把它作为cookie存储到访问者的浏览器上;
4、jQuery将接收这个从AJAX调用来的时间戳信息,并将该哈希值或“令牌”作为表单的隐藏标签而存储;
5、当该表单为处理而被发送,这个时间戳的值(表单中的——译者注)将和存储在cookie中的32位字符“令牌”做比较;
6、如果信息不匹配,或是丢失,又或者时间戳过期,我们将终止表单处理的执行,同时这个垃圾邮件发送者将会把目标转移到另一个简单的猎物上(放弃我们这个目标——译者注)。

实战演习:
核心就3个文件:
1.前端提交发表页面:demo.htm
2.产生令牌页面:token.php
3.提交处理页面:test.php

1.前端提交发表页面:demo.htm

  1. <html>
  2. <head>
  3. <title>提交页面</title>
  4. <script src="jquery.js"></script>
  5. <script type="text/javascript">
  6. $(document).ready(function(){
  7. $.get("token.php",function(txt){
  8.   $(".secure").append('<input type="hidden" name="ts" value="'+txt+'" />');
  9. });
  10. });
  11. </script>
  12. </head>
  13. <body>
  14.  
  15. <form action="test.php" method="post" class="secure">
  16.     Name:<input type="text" name="name" />
  17.     <input type="submit" name="Submit" value="Submit" />
  18. </form>
  19.  
  20. </body>
  21. </html>

这里用jQuery实现AJAX,在页面加载完毕后从token.php获取“令牌”,相当于获取验证码图片。
上面的令牌从下面的文件获取token.php

2.产生令牌页面:token.php

  1. <?php
  2. $token = $_SERVER['REQUEST_TIME'];
  3. //把时间戳与自定义字符串(我这里用的'ieliwb')拼接后进行md5加密,并存入cookie
  4. //参数0说明该cookie随浏览器关闭而失效
  5.  
  6. setcookie('token',md5('ieliwb'.$token), 0, '/');
  7.  
  8. //在产生“令牌”时可以加上防止缓存的代码
  9. # 'Expires' in the past
  10. header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  11. # Always modified
  12. header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
  13. # HTTP/1.1
  14. header("Cache-Control: no-store, no-cache, must-revalidate");
  15. header("Cache-Control: post-check=0, pre-check=0", false);
  16. # HTTP/1.0
  17. header("Pragma: no-cache");
  18. //输出到隐藏的表单
  19. echo $token;
  20. ?>

3.提交处理页面:test.php

  1. <?php
  2. $proceed = false;
  3. $seconds = 60*10;//令牌有效时间
  4. if(isset($_POST['ts']) && isset($_COOKIE['token']) && $_COOKIE['token'] == md5('ieliwb'.$_POST['ts']))
  5. {
  6.     $proceed = true;
  7. }
  8. if(!$proceed)
  9. {
  10.     die('令牌错误!');
  11. }
  12. /**
  13. if(!isset($_POST['ts']) || empty($_POST['ts'])) {
  14.     die('你是机器人吧');
  15. }
  16. if(!isset($_COOKIE['token'])) {
  17.     die('父令牌丢失');
  18. }
  19. if(md5('ieliwb'.$_POST['ts']) != $_COOKIE['token']) {
  20.     die('令牌错误');
  21. }
  22. */
  23. if(((int)$_POST['ts'] + $seconds) < $_SERVER['REQUEST_TIME'])
  24. {
  25.     die('令牌已失效');
  26. }
  27. echo '<h1>Testing:</h1><p>Cookie: '.$_COOKIE['token'].'<br />Timestamp: '. $_POST['ts'].'</p>';
  28. echo '<h1>Success!</h1><br />Here is what you sent:';
  29. print_r($_POST);
  30.  
  31. ?>

到此全部ALL了,测试吧!不过验证码也不是毫无用处,比如可以为那些手动提交垃圾信息的人带来阻碍等。大家可以尝试一下,具体情况当然还得具体对待:),不过图片验证码用户体验确实不好,下篇我将介绍简单的计算运算验证码。

评论

lxzbbjrgg Says:

AD
管理员:不要AD

zzzz Says:

这玩意太容易破解,如果一定要破你,只需要再模拟ajax发一个请求到你的php的地址,再拿到时间戳和cookie的值不就行了

发表新评论