Home > Tech > Wordpress > 使用隐藏输入框阻止垃圾评论

使用隐藏输入框阻止垃圾评论

Add a comment July 21st, 2009 http://s.ibron.co/kB8d0h

看到这个标题,估计你会联想到NoSpamNX。没错,这个idea就是借鉴NoSpamNX的。前几天在网上溜达的时候看到了一篇关于NoSpamNX的介绍,觉得挺不错,决定尝试一下。可惜的是安装之后不能正常使用,估计原因在于我的主题使用了Ajax的评论提交方式,NoSpamNX好像没办法获得评论数据。粗略看了一下代码,觉得也不算太麻烦,遂集成到主题中。

NoSpamNX生成两个Name为随机值的隐藏文本框,其中一个文本框的内容也是随机值,放置在评论表单中,一般的Spam Robot会将此表单所有的项目填充,而正常的访客几乎不可能这么做(当然,无聊地用FireBug看到了这两个文本框然后打算折腾一下的人不算 :!: )。因此,只要判断这两个输入框的内容就知道评论是不是Spam了。

另外,鉴于某些Spam Robot会根据文本框的Name属性来填写内容,我把设计思想改了一下,把真正的留言者名称文本框的Name改成随机值,同时仍然生成两个隐藏文本框,一个Name依然随机,另一个叫”author”,呵呵~~是不是跟YAWASP有点像?好吧,我就是借鉴他的…这样一来,Spam Robot基本上都能被kick out了。

随机值参考NoSpamNX,采用随机数+MD5来产生。生成的数据保存在session里,这样一个访客只用生成一次,直到session过期(默认是24分钟,应该足够了)

啰啰嗦嗦讲了那么多原理,下来开始动手。

增加随机值产生函数

编辑主题的function.php文件,加入如下代码,产生三个随机值。

1
2
3
4
5
6
7
8
9
function Generate_ID()
{
	if (empty($_SESSION['SS_1_ID']))//如果不存在此值,一般是新访问者或者session过期
	{
		$_SESSION['SS_1_ID'] = md5(uniqid(mt_rand(), true));
		$_SESSION['SS_2_ID'] = md5(uniqid(mt_rand(), true));
		$_SESSION['SS_2_VALUE'] = md5(uniqid(mt_rand(), true));
	}//否则不产生新的随机值,使用session中已经保存的
}

修改header.php

修改主题的header.php文件,在适当的位置加入如下代码:session_start();这个适当的位置一般是文件的第3行,即“DOCTYPE”(第一行)和php开始标记(第二行)的下面。

修改评论框(comment.php)

OK,这个算是一个关键部分,请仔细修改并保存备份。

  1. 修改原始的“留言者名称”文本框。找到类似<input type="text" name="author" id="author"的一行,将name换成三个随机值中的一个。我这里改成name="at-<?php echo $SESSION_[SS_ID_1];"
  2. 增加隐藏输入框。找到type=hidden,name=”comment_post_ID”的输入框(<input),在下面一行加入如下代码:
    1
    2
    3
    4
    5
    6
    7
    
    <?php 
    if (mt_rand(1,2) == 1){//两个input位置随机
    	echo '<span id="spamstop" style="display:none"><input type="text" name="author" value="" /><input type="text" name="'.$_SESSION['SS_2_ID'].'" value="'.$_SESSION['SS_2_VALUE'].'" /></span>';
    }else{
    	echo '<span id="spamstop" style="display:none"><input type="text" name="'.$_SESSION['SS_2_ID'].'" value="'.$_SESSION['SS_2_VALUE'].'" /><input type="text" name="author" value="" /></span>';
    }
    ?>

comment.php修改完成~

修改ajax处理文件

打开ajax处理文件(一般是comments-ajax.php),我使用的是这个版本,注意参考。找到$comment_post_ID = (int) $_POST['comment_post_ID'];,在它上面一行开始加入如下代码:

1
2
3
4
5
6
session_start();
if (!empty($_SESSION['SS_1_ID']))
	if (($_POST['author'] != "") ||  //假名称栏有内容
	(!array_key_exists($_SESSION['SS_2_ID'],$_POST)) || //隐藏输入框不存在,可能是直接提交
	($_POST[$_SESSION['SS_2_ID']] != $_SESSION['SS_2_VALUE']) ) //隐藏输入框内容被修改
		fail('Sorry, but your comment seems to be a spam.<br />对不起,您的评论被判定为垃圾评论.');

之后找到"$comment_author = trim(strip_tags($_POST['author']));",将其中的”author”改成在修改评论框中使用的名称,按照我的例子,这里应该改成"$comment_author = trim(strip_tags($_POST['at-'.$_SESSION['SS_1_ID']]));"

到这里,所有修改就完成了。赶快测试一下吧~

Tips

如果主题有设置页面的话,可以给这个功能加一个开关。这样在不想用的时候可以将这个功能关闭。具体的实现就留给大家了,其实是很简单的,参考主题的其他部分应该很容易就能搞定。只是有一点要说一下,如果使用了”开关”来控制这个功能,ajax处理部分也需要获得”开关”的状态,这时不需要在ajax处理文件中再去读取数据库,可以参考comment.php中对”comment-post-id”的传递方式在合适位置加一个hidden类型的input,把”开关”状态放进去,只要保证这个hidden的input在留言表单内,也就是在commentform内,提交的时候就能顺利把参数传过去。

啊~第一次写功能比较复杂的主题修改教程,自我感觉比较烂,还望大家多多包涵,嘿嘿~~

最后要感谢NoSpamNXYAWASP的作者,感谢他想出这么好的点子~~

  1. July 22nd, 2009 at 07:23 | #1
    Reply Quote

    难道是传说中的沙发?

    不知道为什么~~最近几个月一个垃圾留言都没有…以起码一天几十个….

  2. July 22nd, 2009 at 08:43 | #2
    Reply Quote

    @吖Bee
    估计Spam Robot都被叫回家吃饭去了…… ;-)

  3. July 22nd, 2009 at 09:28 | #3
    Reply Quote

    羡慕,能自己改代码解决问题。学习中。。。

  4. July 22nd, 2009 at 12:18 | #4
    Reply Quote

    @shepgala
    呵呵,都是瞎折腾~~

  5. July 22nd, 2009 at 22:10 | #5
    Reply Quote

    也能折腾啊!不错啊

  6. July 26th, 2009 at 00:20 | #6
    Reply Quote

    目前用wp自带的能应付,收藏一下方法先,以后可能用得着。

  7. July 28th, 2009 at 01:07 | #7
    Reply Quote

    终于可以评论上了,你这个评论系统有个超级大的bug
    我用easyComment自动填写评论信息,就被判定为垃圾留言鸟。日!

  8. July 28th, 2009 at 09:57 | #8
    Reply Quote

    @Showfom
    原因就在这篇文章里啊~因为我已经把信息输入框的”name”换掉了,估计easycomment直接根据name值来找文本框,so~~~这个只能算有冲突,不算Bug吧…
    话说记录了Cookie之后再留言的时候就只要输内容,也用不着easycomment了。莫非你很久没来了? :!:

  9. July 28th, 2009 at 16:00 | #9
    Reply Quote

    @Bronco
    经常清空浏览器的缓存是个好习惯,日,肯定根据Name之类默认的,我对你无语 日

  10. July 28th, 2009 at 22:08 | #10
    Reply Quote

    @Showfom
    :!: 清空缓存就好,Cookie不用也清掉吧……
    至于评论系统,就劳烦您老人家手动填一下吧,嘿嘿~~

  11. July 28th, 2009 at 22:26 | #11
    Reply Quote

    @Bronco
    :!: 我直接全部清空 这样爽

    你这种人 就是没长久打算……

  12. July 28th, 2009 at 22:30 | #12
    Reply Quote

    @Showfom
    长久?你是指什么?
    Cookie反正过期之后也会被清掉的,文件又不大~

  13. July 28th, 2009 at 22:33 | #13
    Reply Quote

    @Bronco
    真是笨,假如又碰到访客,和我一样用 easyComment 插件的,整天被判定为XX 日

  14. August 9th, 2009 at 22:06 | #14
    Reply Quote

    @Showfom
    你个鸟人…

  15. August 9th, 2009 at 22:11 | #15
    Reply Quote

    @Bronco
    习惯性我又去点了一下 囧

  16. CM
    October 10th, 2009 at 16:54 | #16
    Reply Quote

    DDDDDDDDDDDDDDDDDDDDDDDDDDD

  17. CM
    October 10th, 2009 at 16:56 | #17
    Reply Quote

    Bronco :
    @Showfom
    你个鸟人…

    引用测试

  18. CM
    October 10th, 2009 at 16:57 | #18
    Reply Quote

    @Showfom
    回复测试

  19. October 10th, 2009 at 17:26 | #19
    Reply Quote

    @CM
    表灌水哇~~~ :!:

  20. edikud
    January 2nd, 2010 at 14:02 | #20
    Reply Quote

    Warning: session_start() [function.session-start]: Cannot send session cookie – headers already sent by (output started at…..

    在适当的位置加入如下代码:session_start();这个适当的位置一般是文件的第3行,即“DOCTYPE”(第一行)和php开始标记(第二行)的下面??????

  21. January 2nd, 2010 at 14:16 | #21
    Reply Quote

    @edikud
    这个应该是你使用了缓存或者gzip压缩,导致在执行session_start的时候cookie已经发送出去了。

  22. edikud
    January 2nd, 2010 at 16:51 | #22
    Reply Quote

    session_start();具体要放到什么位置啊???

  23. edikud
    January 2nd, 2010 at 17:01 | #23
    Reply Quote

    我这里改成name=”at-的吧..

    我本地测试改成name=”at-”….at-”"没有生成随机值,

    我是这样测试的,但没有成功.

  24. edikud
    January 2nd, 2010 at 17:04 | #24
    Reply Quote

    我这里改成name=”at-的吧..

    我本地测试改成name=”at-”….at-”"没有生成随机值,< = <

    > = >我是这样测试的,但没有成功.

  25. January 3rd, 2010 at 18:36 | #25
    Reply Quote

    @edikud
    你把Generate_ID()这个函数放到一个单独的php文件里,在php开始标记后面的一行写”session_start()”试试看。如果session_start没成功的话”name=”那里是不会有值的。

  26. edikud
    January 3rd, 2010 at 20:08 | #26
    Reply Quote

    能发个php文件给我参考下吧….Generate_ID()这个函数我不会用啊???

  27. edikud
    January 7th, 2010 at 15:23 | #27
    Reply Quote

    还是不行啊…Warning: session_start() …. :cry: :?:

  28. January 8th, 2010 at 14:30 | #28
    Reply Quote

    @edikud
    你的主机启用了gzip压缩吧~设定方式不一样对这个也是有影响的,这方面你可以在网上找些资料看看~

  29. January 12th, 2010 at 20:32 | #29
    Reply Quote

    我的主机没有启用gzip压缩啊,http://www.mcooo.com/ 我在functions加上session_start();但提交有错误代码?

  30. January 12th, 2010 at 20:34 | #30
    Reply Quote

    我是用http://www.xiaorsz.com/ comments-ajax

  31. chenming
    January 13th, 2010 at 10:22 | #31
    Reply Quote

    为什么都用php写呢

  32. March 29th, 2010 at 20:36 | #32
    Reply Quote

    但与缓存插件WP Super Cache不兼容啊! :?:

  33. March 29th, 2010 at 22:52 | #33
    Reply Quote

    @edikud
    呃…没用缓存插件,没测试过。这个你可以找些静态缓存和session的文章研究看看,玩wp嘛,不就是折腾么 :smile:

  34. March 29th, 2010 at 23:25 | #34
    Reply Quote

    有时间的话才可以啊! :grin:

  35. March 29th, 2010 at 23:36 | #35
    Reply Quote

    @edikud
    慢慢来嘛~兴趣变成一种负担就不好了,无聊了就折腾几下,忙起来就不管了~ :cool:

  36. March 31st, 2010 at 13:27 | #36
    Reply Quote

    从blogsearch搜到了这篇文章,真的很不错,希望能看到更多的新内容,已经订阅了rssfeed,祝博主好运:)

  37. October 9th, 2010 at 16:23 | #37
    Reply Quote

    @edikud
    恩,我以前安装了WP-SUPER-CACHE后,发现和不少组件不兼容,甚至让我的WORDPRESS DOWN掉,无奈卸载了

  1. [...] 上一篇我讲了如何利用隐藏输入框来组织垃圾评论,今天登陆后台,居然还是发现了一篇垃圾评论~ 这是怎么回事?莫非是我的隐藏输入框不起作用了?不应该啊~本地测试都是没问题的。人肉Spam?更加不可能了,哪个foreigner会找到这个没什么人气小站来投放ad啊… [...]

  2. [...] address of this article is http://heybronco.net/tech/wordpress/use-hidden-input-to-stop-spam/.When you got this here have more than 30 comments. Why not come to check it [...]

  3. August 18th, 2011 at 20:02 | #3

    [...] 上一篇我讲了如何利用隐藏输入框来组织垃圾评论,今天登陆后台,居然还是发现了一篇垃圾评论~ 这是怎么回事?莫非是我的隐藏输入框不起作用了?不应该啊~本地测试都是没问题的。人肉Spam?更加不可能了,哪个foreigner会找到这个没什么人气小站来投放ad啊… [...]

Comments feed