令人头疼的垃圾评论
只要有评论框,就会有垃圾评论出现;只要你文章内容或者是个性化设计让人不满意,你就会收到各种吐槽。
邮件地址的框栏对于Spam commenters来说几乎不存在,他们可以随便伪造一个地址就可以畅所欲言。为了阻止这种极其闹挺的现象在自己的Wordpress站点上发生,果然还是该写写邮箱验证码功能。
没基础的可以直接抄走代码使用,转载请引用来源!
准备工作
- 你的主机具有发送邮件的功能,或者安装了第三方SMTP插件(我用WP SMTP)
- 你知道数据库这个东西是什么
- 你会修改你的主题里的配置文件
- 引用了jQuery
Let's Start!
制作获取验证码的API
我们来编写发送验证码的业务逻辑,原则上不能写在前端,一切验证码的生成与校验都应该在后端进行,否则那些会F12的大佬们会把你的评论系统弄得一团糟。
建立一个数据表,建议结构如下:
为了实现Ajax(/Pjax)的异步效果,将以下代码写出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
function captcha(){ global $wpdb; $mailuser = $_GET['mail']; if($mailuser == ''){ header('HTTP/1.0 500 Internal Server Error'); header('Content-Type:text/plain;charset=UTF-8'); echo '邮件地址未填写'; wp_die(); } header('Content-Type:text/plain;charset=UTF-8'); //检查是否允许发送验证码 $mailinfo = $wpdb->get_row($wpdb->prepare("SELECT * FROM (表名称,自己改) WHERE mailuser = %s",$mailuser)); if($mailinfo->mailuser != $mailuser){ $capt = rand(100000,999999); $table = "验证码生成器用于存放数据的表名称"; //起啥名字都行 $data_array = array( 'mailuser' => $mailuser, //邮箱地址 'lasttime' => time(), //验证码获取时间 'captcha' => $capt, //验证码 'trial' => 10 //10尝试机会 ); $wpdb->insert($table,$data_array); send_captcha($mailuser,$capt); wp_die(); }else if($mailinfo->banned==1){ echo "该邮箱验证码功能被封禁"; wp_die(); }else{ $capt = rand(100000,999999); $table = "验证码生成器用于存放数据的表名称"; //起啥名字都行 $data_array = array( 'lasttime' => time(), 'captcha' => $capt, 'trial' => 10 ); $where_clause = array( 'mailuser' => $mailuser ); $wpdb->update($table,$data_array,$where_clause); $to=$mailuser; send_captcha($mailuser,$capt); wp_die(); } wp_die(); } |
接下来,再添加以下代码,将功能挂到admin_ajax.php中
1 2 |
add_action('wp_ajax_nopriv_captcha', 'captcha'); add_action('wp_ajax_captcha', 'captcha'); |
解释:
为了防止SQL注入查询,使用了wpdb->prepare();进行转义
很容易就能看出来,调用方式为:https://www.lemonpig.cn/wp-admin/admin-ajax.php?action=captcha&mail=邮箱地址
send_captcha()是发送验证码的函数,可以自定义,我的模板如下,各位可以根据自己主题的情况进行更改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
function send_captcha($mailuser,$captcha){ $mail_user_name = akina_option('mail_user_name') ? akina_option('mail_user_name') : 'Poi'; $wp_email = $mail_user_name . '@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])); $subject = '验证码'; $message = ' <table border="1" cellpadding="0" cellspacing="0" width="600" align="center" style="border-collapse: collapse; border-style: solid; border-width: 1; border-color:#ddd;"> <tbody> <tr> <td> <table align="center" border="0" cellpadding="0" cellspacing="0" width="600" height="48" > <tbody> <tr> <td width="100" align="center" style="border-right: 1px solid #ddd;"> <a href="' . home_url() . '/" target="_blank">' . get_option("blogname") . '</a> </td> </tr> </tbody> </table> </td> </tr> <tr> <td style="padding: 20px 40px 0;"> <p><strong>' .trim($mailuser). '</strong>, 你好!</p> <p>验证码为:<strong>'.$captcha.'</strong></p> <center><a href="https://www.lemonpig.cn/" target="_blank" style="background-color: #6ec3c8; border-radius: 10px; display:inline-block; color:#fff; padding: 15px 20px 15px 20px; text-decoration: none; margin-top: 20px; margin-bottom: 20px;">点击查看完整内容</a></center> </td> </tr> <tr> <td align="center" valign="center" height="38" style="font-size: 0.8rem; color: #999;">© ' . get_option("blogname") . '</td> </tr> </tbody> </table> '; $from = "From: \"" . get_option('blogname') . "\" <$wp_email>"; $headers = "$from\nContent-Type: text/html; charset=" . get_option('blog_charset') . "\n"; if(wp_mail($mailuser, $subject, $message, $headers)){ echo "验证码发送成功"; }else echo "服务器内部错误"; } |
编写前端调用
在comments.php中添加验证码输入框(注意!!!这是一段Javascript代码,写在HTML部分!!不是PHP),可以参考我的评论模板(F12也行吧)
编写ajax请求程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function get_captcha(){ email = $("#email").val(); jQuery.ajax({ url: Poi.ajaxurl, data: jQuery(this).serialize() + "&action=captcha" + "&mail=" + email, type: jQuery(this).attr('method'), dataType: "text", beforeSend: addComment.createButterbar("正在获取验证码...."), error: function(request) { var t = addComment; t.createButterbar(request.responseText); }, success: function(data) { var t = addComment; t.createButterbar(data); } }); } |
我的邮箱输入框id是email,故有#email
1 |
t.createButterbar(request.responseText); |
那个是消息提醒,可以自定义,addComment也是自定义,可以不用,我是借用了自己主题里的一个类。提醒框亦可这么写(需要自写css,允许F12看我的)
1 2 3 4 5 6 7 8 9 10 11 |
function clear(e) { if (jQuery(".butterBar").length > 0) { jQuery(".butterBar").remove(); } } function show(message) { clear(); jQuery("body").append('<div class="butterBar butterBar--center"><p class="butterBar-message">' + message + '</p></div>'); setTimeout("jQuery('.butterBar').remove()", 3000); } |
后端验证
直接上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
// 评论验证码 function comment_captcha() { if (!is_user_logged_in()){ if(!$_POST['captcha']){ siren_ajax_comment_err('未填写验证码'); } //检查验证码的正确性 $mail = $_POST['email']; global $wpdb; $mailinfo = $wpdb->get_row($wpdb->prepare("SELECT * FROM **表名称** WHERE mailuser = %s",$mail)); if($mailinfo->mailuser !== $mail){ //数据库中不存在此邮箱,用户没有获取验证码 siren_ajax_comment_err('此邮箱地址未获取验证码'); }else if($mailinfo->banned){ siren_ajax_comment_err('错误:该邮箱验证码功能被封禁'); }else if(!$mailinfo->trial){ siren_ajax_comment_err('验证码尝试机会用尽,请重新获取验证码'); }else if($_POST['captcha']!=$mailinfo->captcha){ $table = "**表名称**"; $data_array = array( 'trial' => $mailinfo->trial-1 ); $where_clause = array( 'mailuser' => $mail ); $wpdb->update($table,$data_array,$where_clause); siren_ajax_comment_err('验证码错误,剩余' . (string)($mailinfo->trial-1) . '次机会'); }else if($_POST['captcha']==$mailinfo->captcha&&$mailinfo->trial==-1){ siren_ajax_comment_err('验证码已失效,请重新获取验证码'); }else{ $table = "**表名称**"; $data_array = array( 'trial' => -1 ); $where_clause = array( 'mailuser' => $mail ); $wpdb->update($table,$data_array,$where_clause); } } } add_action('pre_comment_on_post', 'comment_captcha'); |
1 |
siren_ajax_comment_err('未填写验证码'); |
是消息回显的函数,是主题自带的,可以自定义。
大功告成
你可能需要一点时间去调试,但这似乎并不难,调试完了,Spam Commenters就不能伪造地址了!
要不要试试我的验证码功能?就在下面!
叨叨几句... 12 条评论
快来快来
你好
@不值一提网友
hello!
哇哦非常不错给你投个币
@世尊
哈哈,多谢呀。要是需要帮助的话可以呼我哦~
播主这个网页做的不错,可以的话能出一下教程吗【doge】
@yanglin
多谢支持,我会写一个系统的教程的,只不过最近有点忙……教程写完后放在哪里好呢?CSDN?
@LemonPig
慢慢来,至于存放平台还是由up自己决定啦
收藏了确实不错
@233
谢谢支持!
其实对于评论来说用邮箱验证码或许是有些繁琐了,或许可以试试看添加数字验证码或者Recaptcha v3,体验都是很好的。
@DeKvin
要是图形验证码啥的就不能保证这一点了。
主要还是用来防止用虚假的地址来灌水呀