「主题通用」全站文章评论增加验证码插图

说干就干,直接对接一下极验,再把后端验证接口部署一下,目前仅对文章开启了评论验证。详细的配置内容待我睡醒以后补充。

由于本站所使用的主题为「nicetheme」开发的,核心文件被加密了。我尝试过解密,不过这种字节码加密的还是算了吧。对此,我也只能另辟蹊径了。

思路分析

由于我的主题提交评论的时候使用的是WordPress自带的「ajax」action,所以「ajax_comment」是一个关键字,这里也是添加评论验证的突破口。

我这里是默认全局启用了评论验证,所以可以这样做:

如果POST的表单中包含ajax_comment,则触发评论验证码校验,没有则放行即可。

经查阅WordPress的官方文档后,有一个钩子非常适合我们的验证:「preprocess_comment

很好,突破口找到了,那么我们来找找验证。

验证挑选

这里我就推荐「hCaptcha」和「极验」,要问为什么的话,因为是凌晨写的代码,脑子里就只有这两个。

对接方式都差不到太多,我这里使用的是极验,推荐用行为验证 4.0(其他站点除外),有条件的话你可以使用收费版。

「主题通用」全站文章评论增加验证码插图2

有人也许会担心是否能够被破解,我只能说很难也很容易,也看对哪些人来说吧。如果是专门搞逆向JS的人来说,非常简单。不过防止恶意攻击这种,我觉得足够了。

主题改造

前端改造

如果你的主题是通过ajax的方式进行评论的,那么以下代码将会极大程度的帮助你:

  function initGeetestCallback(captchaObj) {
    globalCaptchaObj = captchaObj
    // 在这里可以进行其他处理操作
    globalCaptchaObj.onReady(function () {
      isLoading = false
      console.warn('验证码加载完毕')
    })

    globalCaptchaObj.onSuccess(function () {
      // 处理数据
      var captcha = {
        captcha: globalCaptchaObj.getValidate(),
      }

      var form = jQuery('#commentform')

      submitButton.prop('disabled', true).prop('value', '正在提交中...')

      submitCommentForm(form, captcha)

      globalCaptchaObj.reset()
    })

    globalCaptchaObj.onError((error) => {
      ncPopupTips(1, '验证码加载问题,请刷新页面后重试')
      return false
    })

    globalCaptchaObj.onClose(() => {
      ncPopupTips(1, '需通过验证才能进行评论')
      globalCaptchaObj.reset()
      return false
    })
  }

这个是我让AI学习「极验」官方例子写的一个初始化回调,初始化的话就和官方长得不多,无非就是把回调替换为了initGeetestCallback:

    initGeetest4(
      {
        captchaId: captchaId,
        product: product,
      },
      initGeetestCallback
    )

然后自己按照主题的提交评论的方法,编写一下「submitCommentForm」这个函数就行。

后端改造

在可以编辑的「functions.php」文件中,增加以下代码

function load_gt4_js_if_comments_open()
{
    if (comments_open() && is_single()) {
        // 获取当前启用主题的js目录路径
        $theme_js_dir = get_template_directory_uri() . '/js/';

        // 注册gt4.js文件
        wp_register_script('gt4', $theme_js_dir . 'gt4.js', array('jquery'), '4.0', true);

        // 将变量传递给gt4.js脚本
        $variables = array(
            'isOpen_verify_comment' => false,
        );
        wp_localize_script('gt4', 'comment_verify', $variables);

        // 加载gt4.js文件
        wp_enqueue_script('gt4');
    }
}
add_action('wp_enqueue_scripts', 'load_gt4_js_if_comments_open');

此段代码用于加载「极验」验证的核心文件,从其官方文档出下载上传至「ThemeName\js」目录即可。

定义二次验证

function verify_geetest($captcha_id, $captcha_output, $gen_time, $lot_number, $pass_token)
{
    // 极验参数信息
    $captcha_key = '您的业务配置中的验证Key';
    $api_server  = 'http://gcaptcha4.geetest.com';

    // 生成签名
    $lotnumber_bytes = utf8_encode($lot_number);
    $prikey_bytes    = utf8_encode($captcha_key);
    $sign_token      = hash_hmac('sha256', $lotnumber_bytes, $prikey_bytes);

    // 请求极验二次验证接口,校验用户验证状态
    $query = array(
        "lot_number"     => $lot_number,
        "captcha_output" => $captcha_output,
        "pass_token"     => $pass_token,
        "gen_time"       => $gen_time,
        "sign_token"     => $sign_token,
    );
    $url = $api_server . '/validate' . '?captcha_id=' . $captcha_id;

    $response = wp_remote_post($url, array(
        'method'      => 'POST',
        'timeout'     => 15,
        'httpversion' => '2.0',
        'headers'     => array(),
        'body'        => $query,
    ));

    return json_decode(wp_remote_retrieve_body($response), true);
}

处理评论回调

这里只给一个大概的轮子,我相信凭借你的聪明头脑一定能学会:

function custom_preprocess_comment_filter($commentdata)
{
    // 获取全局的 POST 内容
    $actionName = '你的action判断';

    $post_data = $_POST;
    if (!isset($post_data['action']) || $post_data['action'] != $actionName) {
        return $commentdata;
    }

    // TODO: 处理action 为 $actionName 的情况



    // 存在则判断验证码
    $captcha        = $post_data['captcha'];
    $captcha_id     = $captcha['captcha_id'];
    $captcha_output = $captcha['captcha_output'];
    $gen_time       = $captcha['gen_time'];
    $lot_number     = $captcha['lot_number'];

    $pass_token = $captcha['pass_token'];

    $result = verify_geetest($captcha_id, $captcha_output, $gen_time, $lot_number, $pass_token);

    if ($result['status'] == 'success') {
        if ($result['result'] == 'success') {
            // 二次校验成功
            return $commentdata;
        } else {
            wp_send_json_error('验证码校验失败,请重试');
        }
    } else {
        wp_send_json_error('请求异常,请重试');
    }
}

如果实在是学不会的话,可以交给AI帮助你完成代码,或者在下方留言,邮箱信息一定要填写正确哦!

那么处理完毕后,我们的评论验证码基本上就改造完成了。

效果演示

给大伙儿看看效果如何:

视频可能加载较慢,稍作等待一下即可