相信建立过独立博客的人都有过体会,就是当博客访问量上来之后都会遭遇恶意注册和垃圾评论的困扰,我的博客也是受到过恶意注册的影响,虽然真正没什么人来注册,但也不能接受机器人恶意注册 。。。。。极验验证是国内的新一代基于行为的交互式验证方式,可以有效防止验证码**,下面就来说下如何在WordPress中集成极验验证,我为了减少插件的安装,就直接把极验验证集成到主题中去了,有需要的可以访问主题源码,我的主题是在Dobby的基础上进行改进的。添加极验验证后的登录和注册页面如下:
1 获取极验验证的id和key
首先,前往极验验证官网进行注册并登陆,注册后默认使用免费版本的优惠套餐,登录后台后,选择行为验证,进入管理,新增网站,添加网站后会得到id和key值,留下备用。接着下载PHP版本的sdk,前往下载。加压后得到四个目录,把这几个目录全部拷贝到主题对应目录下面(根据个人主题需要放置到合适目录下即可),然后修改config下的config.php,填入对应的id和key。你也可以把这几个目录拷贝到PHP网站目录下,运行示例,static/login.html。login.html的对应解释如下所示:
2 添加登录和注册验证
如果不清楚如何在登录和注册表单中添加自定义的字段,可以参考我的前一篇文章《WordPress自定义登录和注册页面样式并且添加验证码》,同时在这篇文章也会重温下方法。
首先在登录页面添加自定义的验证码框,因为极验验证需要使用特定的js脚本文件,而且脚本文件的加载有先后顺序,所以现在登录页面引入必要的js和css,如下,在functions.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
|
//添加自定义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中添加函数:
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中添加代码:
展开/折叠代码
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'],是我在登录和注册表单中添加的一个隐藏的输入框,如果内容不为空,就代表是机器人填写了,拒绝验证通过, 。
下面再在注册页面添加极验验证,同样在functions.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
}
|
我这里多了一个选择,就是在极验验证的服务器宕机的时候,切换回我自己的图片验证码。对注册表单提交的验证码在服务器上做校验:
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脚本,我这里的主题对是否开启评论验证添加一个开关按钮,没有的话可以删除相关代码,代码如下:
展开/折叠代码
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
}
}
}
|
同样的,可以在服务器端对提交的评论进行拦截验证,添加代码如下:
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( "'", ''', $incoming_comment['comment_content'] );
return( $incoming_comment );
}
add_filter( 'preprocess_comment', 'plc_comment_post', '', 1);
|
接下来在评论表单中添加验证码显示,找到主题下面的评论表单的位置,我的在主题根目录下的comments.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,所以在前面的代码中对它的提交事件进行了拦截。
好了,我们已经完成了登录、注册、评论的极验验证,希望可以有效地防止恶意注册和垃圾评论,只从我的博客添加了验证以来就没遇到过恶意注册的了。