WordPress添加极验验证防止垃圾评论和恶意注册

时间:2024-03-27 17:00:27

相信建立过独立博客的人都有过体会,就是当博客访问量上来之后都会遭遇恶意注册和垃圾评论的困扰,我的博客也是受到过恶意注册的影响,虽然真正没什么人来注册,但也不能接受机器人恶意注册 WordPress添加极验验证防止垃圾评论和恶意注册 。。。。。极验验证是国内的新一代基于行为的交互式验证方式,可以有效防止验证码**,下面就来说下如何在WordPress中集成极验验证,我为了减少插件的安装,就直接把极验验证集成到主题中去了,有需要的可以访问主题源码,我的主题是在Dobby的基础上进行改进的。添加极验验证后的登录和注册页面如下:

WordPress添加极验验证防止垃圾评论和恶意注册WordPress添加极验验证防止垃圾评论和恶意注册WordPress添加极验验证防止垃圾评论和恶意注册

1 获取极验验证的id和key

首先,前往极验验证官网进行注册并登陆,注册后默认使用免费版本的优惠套餐,登录后台后,选择行为验证,进入管理,新增网站,添加网站后会得到id和key值,留下备用。接着下载PHP版本的sdk,前往下载。加压后得到四个目录,把这几个目录全部拷贝到主题对应目录下面(根据个人主题需要放置到合适目录下即可),然后修改config下的config.php,填入对应的id和key。你也可以把这几个目录拷贝到PHP网站目录下,运行示例,static/login.html。login.html的对应解释如下所示:

WordPress添加极验验证防止垃圾评论和恶意注册

2 添加登录和注册验证

如果不清楚如何在登录和注册表单中添加自定义的字段,可以参考我的前一篇文章《WordPress自定义登录和注册页面样式并且添加验证码》,同时在这篇文章也会重温下方法。

首先在登录页面添加自定义的验证码框,因为极验验证需要使用特定的js脚本文件,而且脚本文件的加载有先后顺序,所以现在登录页面引入必要的js和css,如下,在functions.php中添加钩子函数:

展开/折叠代码
//添加自定义CSS,用于修改登录页面样式,可以先打开默认的登录界面,进入页面调试,通过自定义样式来覆盖默认的样式 function custom_login() { ?> <link rel="stylesheet" type="text/css" href="<?php echo get_template_directory_uri(); ?>/static/css/login_style.css" /> <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/static/js/jquery.min.js"></script> <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/inc/Geetest/static/gt.js"></script> <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/static/js/login.js"></script>; <script type="text/javascript"> var handlerEmbed = function (captchaObj) { $("#wp-submit").click(function (e) { var validate = captchaObj.getValidate(); if (!validate) { $("#notice")[0].className = "show"; setTimeout(function () { $("#notice")[0].className = "hide"; }, 2000); e.preventDefault(); } }); // 将验证码加到id为captcha的元素里,同时会有三个input的值:geetest_challenge, geetest_validate, geetest_seccode captchaObj.appendTo("#embed-captcha"); captchaObj.onReady(function () { $("#wait")[0].className = "hide"; }); // 更多接口参考:http://www.geetest.com/install/ps/idx-client-sdk.html }; $.ajax({ // 获取id,challenge,success(是否启用failback) url: "<?php echo get_template_directory_uri() . '/inc/Geetest/web/StartCaptchaServlet.php'; ?>?t=" + (new Date()).getTime(), // 加随机数防止缓存 type: "get", dataType: "json", success: function (data) { console.log(data); // 使用initGeetest接口 // 参数1:配置参数 // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件 initGeetest({ https: true, gt: data.gt, challenge: data.challenge, new_captcha: data.new_captcha, product: "popup", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效 offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注 // 更多配置参数请参见:http://www.geetest.com/install/ps/idx-client-sdk.html#config }, handlerEmbed); } }); </script> <?php } add_action('login_head', 'custom_login');
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
46
47
48
49
50
51
52
//添加自定义CSS,用于修改登录页面样式,可以先打开默认的登录界面,进入页面调试,通过自定义样式来覆盖默认的样式
function custom_login() {
    ?>
    <link rel="stylesheet" type="text/css" href="<?php echo get_template_directory_uri(); ?>/static/css/login_style.css" />
    <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/static/js/jquery.min.js"></script>
    <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/inc/Geetest/static/gt.js"></script>
    <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/static/js/login.js"></script>;
    <script type="text/javascript">
     var handlerEmbed = function (captchaObj) {
    $("#wp-submit").click(function (e) {
        var validate = captchaObj.getValidate();
            if (!validate) {
                $("#notice")[0].className = "show";
                setTimeout(function () {
                    $("#notice")[0].className = "hide";
                }, 2000);
                e.preventDefault();
            }
    });
    // 将验证码加到id为captcha的元素里,同时会有三个input的值:geetest_challenge, geetest_validate, geetest_seccode
    captchaObj.appendTo("#embed-captcha");
    captchaObj.onReady(function () {
        $("#wait")[0].className = "hide";
    });
    // 更多接口参考:http://www.geetest.com/install/ps/idx-client-sdk.html
};
 
$.ajax({
    // 获取id,challenge,success(是否启用failback)
    url: "<?php echo get_template_directory_uri() . '/inc/Geetest/web/StartCaptchaServlet.php'; ?>?t=" + (new Date()).getTime(), // 加随机数防止缓存
    type: "get",
    dataType: "json",
    success: function (data) {
        console.log(data);
        // 使用initGeetest接口
        // 参数1:配置参数
        // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
        initGeetest({
         https: true,
            gt: data.gt,
            challenge: data.challenge,
            new_captcha: data.new_captcha,
            product: "popup", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
            offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
            // 更多配置参数请参见:http://www.geetest.com/install/ps/idx-client-sdk.html#config
        }, handlerEmbed);
    }
});
</script>
    <?php
}
add_action('login_head', 'custom_login');

我们需要使用session来存储验证数据,因此需要开启session,在functions.php最前面(第一个<?php后面)添加session_start();

在登录表单中添加显示极验验证的密码框,同样在functions中添加函数:

//在登录框添加验证码 function custom_login_message() { ?> <?php if($_SESSION['gtserver'] == 1){ ?> <div id="embed-captcha"></div> <p id="wait" class="show">正在加载验证码......</p> <p id="notice" class="hide">请先完成验证</p> <?php } ?> <input id="check_human" class="check_human" value="" type="text" name="check_human" /> <p class="forget_password"> <a href="<?php echo wp_lostpassword_url( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); ?>" title="忘记密码">忘记密码?</a> </p> <?php } add_action('login_form', 'custom_login_message');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//在登录框添加验证码
function custom_login_message() {
?>
<?php if($_SESSION['gtserver'] == 1){ ?>
    <div id="embed-captcha"></div>
    <p id="wait" class="show">正在加载验证码......</p>
    <p id="notice" class="hide">请先完成验证</p>
    <?php } ?>
    <input id="check_human" class="check_human" value="" type="text" name="check_human" />
    <p class="forget_password">
        <a href="<?php echo wp_lostpassword_url( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); ?>" title="忘记密码">忘记密码?</a>
    </p>
<?php
}
add_action('login_form', 'custom_login_message');

至此,我们已经完成了登录页面验证码的添加,我们已经在前端进行了验证码的校验,可以不在服务器上进行再次校验,不过,我为了以防万一,还是在服务器上进行了校验。同样的,在functions.php中添加代码:

展开/折叠代码
function check_extra_login_fields($user, $username='', $password='') { require_once( get_template_directory() . '/inc/Geetest/web/VerifyLoginServlet.php'); if ( !$_SESSION['gtserver_result'] && $_SESSION['gtserver']) { $error = new WP_Error(); $error->add( 'not_human', "<strong>错误</strong>: 验证码错误!" ); return $error; } if($_POST['check_human'] !== ""){ $error = new WP_Error(); $error->add( 'not_human', "<strong>错误</strong>: 机器人不能登录!" ); return $error; } else{ return $user; } } add_filter( 'wp_authenticate_user', 'check_extra_login_fields', 10, 2 );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function check_extra_login_fields($user, $username='', $password='') {
require_once( get_template_directory() . '/inc/Geetest/web/VerifyLoginServlet.php');
    if ( !$_SESSION['gtserver_result'] && $_SESSION['gtserver']) {
        $error = new WP_Error();
        $error->add( 'not_human', "<strong>错误</strong>: 验证码错误!" );
        return $error;
    }
    
    if($_POST['check_human'] !== ""){
        $error = new WP_Error();
        $error->add( 'not_human', "<strong>错误</strong>: 机器人不能登录!" );
        return $error;
    }
    else{
        return $user;
    }
}
add_filter( 'wp_authenticate_user', 'check_extra_login_fields', 10, 2 );

这里的$_POST['check_human'],是我在登录和注册表单中添加的一个隐藏的输入框,如果内容不为空,就代表是机器人填写了,拒绝验证通过, WordPress添加极验验证防止垃圾评论和恶意注册WordPress添加极验验证防止垃圾评论和恶意注册WordPress添加极验验证防止垃圾评论和恶意注册

下面再在注册页面添加极验验证,同样在functions.php中添加代码:

add_action( 'register_form', 'show_extra_register_fields' ); function show_extra_register_fields(){ ?> <p> <label for="password">密码<br/> <input id="password" class="input" type="password" tabindex="30" size="25" value="" name="password" /> </label> </p> <p> <label for="repeat_password">请重复密码<br/> <input id="repeat_password" class="input" type="password" tabindex="40" size="25" value="" name="repeat_password" /> </label> </p> <?php if($_SESSION['gtserver']){ ?> <div id="embed-captcha"></div> <p id="wait" class="show">正在加载验证码......</p> <p id="notice" class="hide">请先完成验证</p> <?php }else{?> <p> <label for="check_human_2">请输入验证码:<br/> <input id="check_human_2" class="input" type="text" tabindex="40" size="25" value="" name="check_human_2" /> <img id="check_img" title="点击刷新" src="<?php echo get_template_directory_uri(); ?>/inc/ValidateCode/CheckCode.php" align="absbottom" οnclick="this.src='<?php echo get_template_directory_uri(); ?>/inc/ValidateCode/CheckCode.php?'+Math.random();"></img> <a href="#" οnclick="refresh_check()">看不清?换一张</a> </label> </p> <?php }?> <input id="check_human" class="check_human" type="text" value="" name="check_human" /> <?php }
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
add_action( 'register_form', 'show_extra_register_fields' );
function show_extra_register_fields(){
?>
    <p>
        <label for="password">密码<br/>
            <input id="password" class="input" type="password" tabindex="30" size="25" value="" name="password" />
        </label>
    </p>
    <p>
        <label for="repeat_password">请重复密码<br/>
            <input id="repeat_password" class="input" type="password" tabindex="40" size="25" value="" name="repeat_password" />
        </label>
    </p>
    <?php if($_SESSION['gtserver']){ ?>
    <div id="embed-captcha"></div>
    <p id="wait" class="show">正在加载验证码......</p>
    <p id="notice" class="hide">请先完成验证</p>
    <?php }else{?>
    <p>
        <label for="check_human_2">请输入验证码:<br/>
         <input id="check_human_2" class="input" type="text" tabindex="40" size="25" value="" name="check_human_2" />
         <img id="check_img" title="点击刷新" src="<?php echo get_template_directory_uri(); ?>/inc/ValidateCode/CheckCode.php" align="absbottom" onclick="this.src='<?php echo get_template_directory_uri(); ?>/inc/ValidateCode/CheckCode.php?'+Math.random();"></img>
        
         <a href="#" onclick="refresh_check()">看不清?换一张</a>
        </label>
    </p>
    <?php }?>
    <input id="check_human" class="check_human" type="text" value="" name="check_human" />
<?php
}

我这里多了一个选择,就是在极验验证的服务器宕机的时候,切换回我自己的图片验证码。对注册表单提交的验证码在服务器上做校验:

//检查两次密码是否输入一致,以及检查验证码是否正确 add_action( 'register_post', 'check_extra_register_fields', 10, 3 ); function check_extra_register_fields($login, $email, $errors) { require_once( get_template_directory() . '/inc/Geetest/web/VerifyLoginServlet.php'); if ( $_POST['password'] !== $_POST['repeat_password'] ) { $errors->add( 'passwords_not_matched', "<strong>错误</strong>:两次密码不一致" ); return $error; } if($_SESSION['gtserver']){ if ( !$_SESSION['gtserver_result'] ) { $errors->add( 'not_human', "<strong>错误</strong>:验证码错误!" ); return $error; } }else{ if($_POST['check_human_2'] !== $_SESSION['authnum_session']){ $errors->add( 'not_human', "<strong>错误</strong>:验证码错误!" ); return $error; } } if($_POST['check_human'] !== ""){ $error->add( 'not_human', "<strong>错误</strong>: 机器人不能注册!" ); return $error; } }
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
//检查两次密码是否输入一致,以及检查验证码是否正确
add_action( 'register_post', 'check_extra_register_fields', 10, 3 );
function check_extra_register_fields($login, $email, $errors) {
require_once( get_template_directory() . '/inc/Geetest/web/VerifyLoginServlet.php');
    if ( $_POST['password'] !== $_POST['repeat_password'] ) {
        $errors->add( 'passwords_not_matched', "<strong>错误</strong>:两次密码不一致" );
        return $error;
    }
    
    if($_SESSION['gtserver']){
    if ( !$_SESSION['gtserver_result'] ) {
        $errors->add( 'not_human', "<strong>错误</strong>:验证码错误!" );
        return $error;
    }
    }else{
     if($_POST['check_human_2'] !== $_SESSION['authnum_session']){
     $errors->add( 'not_human', "<strong>错误</strong>:验证码错误!" );
        return $error;
     }
    }
    
    if($_POST['check_human'] !== ""){        
        $error->add( 'not_human', "<strong>错误</strong>: 机器人不能注册!" );
        return $error;
    }
}

好了,到这里,我们已经完成了在登录和注册页面添加极验验证的功能,可以前往我的博客的登录和注册页面进行体验,登录注册

3 给文章评论添加极验验证

我这里的主题针对评论页面新建了一个comments.php文件,功能与主题默认的functions.php一样,如果没有comments文件,可以把一下代码添加在functions.php中。首先在评论页面添加必要的js脚本,我这里的主题对是否开启评论验证添加一个开关按钮,没有的话可以删除相关代码,代码如下:

展开/折叠代码
/*评论验证*/ if(grace_option('is_comment_check')){ add_action( 'wp_head' , 'comment_check_head' ); function comment_check_head() { if ( (is_single()||is_page()) && !is_user_logged_in()) { session_start(); ?> <style type="text/css"> #embed-captcha { min-width: 100%!important; margin: 0 auto; } #embed-captcha > div{ width: 100%!important; } .show { display: block; } .hide { display: none; } #notice { color: red; } </style> <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/static/js/jquery.min.js"></script> <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/inc/Geetest/static/gt.js"></script> <script type="text/javascript"> var handlerEmbed = function (captchaObj) { $("#submit").click(function (e) { var validate = captchaObj.getValidate(); if (!validate) { $("#notice")[0].className = "show"; setTimeout(function () { $("#notice")[0].className = "hide"; }, 2000); e.preventDefault(); } }); captchaObj.appendTo("#embed-captcha"); captchaObj.onReady(function () { $("#wait")[0].className = "hide"; }); }; $.ajax({ url: "<?php echo get_template_directory_uri() . '/inc/Geetest/web/StartCaptchaServlet.php'; ?>?t=" + (new Date()).getTime(), type: "get", dataType: "json", success: function (data) { console.log(data); initGeetest({ https: true, gt: data.gt, challenge: data.challenge, new_captcha: data.new_captcha, product: "popup", offline: !data.success }, handlerEmbed); } }); </script> <?php } } }
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*评论验证*/
if(grace_option('is_comment_check')){
add_action( 'wp_head' , 'comment_check_head' );
function comment_check_head() {
if ( (is_single()||is_page()) && !is_user_logged_in())
{
session_start();
?>
<style type="text/css">
#embed-captcha {
min-width: 100%!important;
    margin: 0 auto;
}
#embed-captcha > div{
width: 100%!important;
}
.show {
    display: block;
}
.hide {
    display: none;
}
#notice {
    color: red;
}
     </style>
<script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/static/js/jquery.min.js"></script>
<script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/inc/Geetest/static/gt.js"></script>
<script type="text/javascript">
     var handlerEmbed = function (captchaObj) {
    $("#submit").click(function (e) {
        var validate = captchaObj.getValidate();
            if (!validate) {
                $("#notice")[0].className = "show";
                setTimeout(function () {
                    $("#notice")[0].className = "hide";
                }, 2000);
                e.preventDefault();
            }
    });
    captchaObj.appendTo("#embed-captcha");
    captchaObj.onReady(function () {
        $("#wait")[0].className = "hide";
    });
};
$.ajax({
    url: "<?php echo get_template_directory_uri() . '/inc/Geetest/web/StartCaptchaServlet.php'; ?>?t=" + (new Date()).getTime(),
    type: "get",
    dataType: "json",
    success: function (data) {
        console.log(data);
        initGeetest({
         https: true,
            gt: data.gt,
            challenge: data.challenge,
            new_captcha: data.new_captcha,
            product: "popup",
            offline: !data.success
        }, handlerEmbed);
    }
});
</script>
<?php
}
}
}

同样的,可以在服务器端对提交的评论进行拦截验证,添加代码如下:

function plc_comment_post( $incoming_comment ) { if(grace_option('is_comment_check') && $_SESSION['gtserver']){ if ( !$_SESSION['gtserver_result'] ) { exit; } } $incoming_comment['comment_content'] = htmlspecialchars($incoming_comment['comment_content']); $incoming_comment['comment_content'] = str_replace( "'", '&apos;', $incoming_comment['comment_content'] ); return( $incoming_comment ); } add_filter( 'preprocess_comment', 'plc_comment_post', '', 1);
1
2
3
4
5
6
7
8
9
10
11
function plc_comment_post( $incoming_comment ) {
if(grace_option('is_comment_check') && $_SESSION['gtserver']){
if ( !$_SESSION['gtserver_result'] ) {
exit;
}
}
    $incoming_comment['comment_content'] = htmlspecialchars($incoming_comment['comment_content']);
    $incoming_comment['comment_content'] = str_replace( "'", '&apos;', $incoming_comment['comment_content'] );
    return( $incoming_comment );
}
add_filter( 'preprocess_comment', 'plc_comment_post', '', 1);

接下来在评论表单中添加验证码显示,找到主题下面的评论表单的位置,我的在主题根目录下的comments.php中,我把验证码添加到了昵称和邮箱输入框的后面,代码如下:

<?php if(grace_option('is_comment_check') && $_SESSION['gtserver']){ ?> <div class="col-md-6 mt-3"> <div id="embed-captcha"></div> </div> <div class="col-md-6 mt-3"> <p id="wait" class="show">正在加载验证码......</p> <p id="notice" class="hide">抱歉,请先完成验证,再评论。</p> </div> <?php } ?>
1
2
3
4
5
6
7
8
9
<?php if(grace_option('is_comment_check') && $_SESSION['gtserver']){ ?>
<div class="col-md-6 mt-3">
<div id="embed-captcha"></div>     
</div>
<div class="col-md-6 mt-3">
<p id="wait" class="show">正在加载验证码......</p>
<p id="notice" class="hide">抱歉,请先完成验证,再评论。</p>
</div>
<?php } ?>

我的评论提交的按钮id是submit,所以在前面的代码中对它的提交事件进行了拦截。

好了,我们已经完成了登录、注册、评论的极验验证,希望可以有效地防止恶意注册和垃圾评论,只从我的博客添加了验证以来就没遇到过恶意注册的了。 WordPress添加极验验证防止垃圾评论和恶意注册  WordPress添加极验验证防止垃圾评论和恶意注册  WordPress添加极验验证防止垃圾评论和恶意注册