【教程】为WordPress后台登录添加验证码

2026-04-21 20:20:54 1点赞 0收藏 0评论

最近我的网站后台频繁遭到爆破,日志里充斥着各种弱密码尝试。

为降低安全风险,避免恶意请求反复占用服务器资源,我决定在 WordPress 登录页加入一个简单的验证码。

这样能在用户输入密码的同时,多一道校验,拦截绝大多数自动化爆破工具。

首先进入后台,在侧边栏——外观——主题文件编辑器中,选择functions.php,在文件内容底部添加代码:

function start_session_for_captcha() { if ( in_array($GLOBALS['pagenow'], ['wp-login.php','wp-register.php']) && !session_id() ) { @ob_start(); session_start(); // 不要立即关闭 session,让登录验证能读取 } } add_action('init', 'start_session_for_captcha', 1); // 生成验证码表达式和答案 function generate_captcha() { $num1 = rand(10, 99); $num2 = rand(10, 99); $operator = ['+', '-'][rand(0,1)]; if ($operator === '-' && $num1 < $num2) { list($num1, $num2) = [$num2, $num1]; } $_SESSION['captcha_answer'] = ($operator === '+') ? $num1 + $num2 : $num1 - $num2; $_SESSION['captcha_expression'] = "$num1 $operator $num2"; return $_SESSION['captcha_expression']; } // 登录表单显示验证码 function add_captcha_to_login_form() { if (!isset($_SESSION['captcha_expression'])) { generate_captcha(); } $expression = $_SESSION['captcha_expression']; echo "

验证码:$expression = ?

<script> document.getElementById('refresh-captcha').addEventListener('click', function() { const btn = this; btn.style.transition='transform 0.3s'; btn.style.transform='rotate(360deg)'; setTimeout(()=>{btn.style.transform='rotate(0deg)';},300); fetch('" . admin_url('admin-ajax.php') . "?action=refresh_captcha&_=' + new Date().getTime()) .then(r=>r.json()) .then(data=>{ if(data.success){ document.querySelector('#login-captcha label').innerText='验证码:'+data.data.expression+' = ?'; document.querySelector('#captcha').value=''; }else{ alert(data.data || '刷新失败,请重试'); } }).catch(e=>{ console.error('刷新验证码失败:',e); alert('刷新验证码失败,请重试'); }); }); script>"; } add_action('login_form', 'add_captcha_to_login_form'); // Ajax 刷新验证码 function ajax_refresh_captcha() { if (!session_id()) session_start(); $expression = generate_captcha(); session_write_close(); // 仅在 Ajax 刷新后释放锁 wp_send_json_success(['expression'=>$expression]); } add_action('wp_ajax_refresh_captcha', 'ajax_refresh_captcha'); add_action('wp_ajax_nopriv_refresh_captcha', 'ajax_refresh_captcha'); // 登录验证 function validate_captcha_on_login($user, $username, $password){ if(!session_id()) session_start(); if(!isset($_POST['captcha']) || !is_numeric($_POST['captcha'])){ return new WP_Error('captcha_error','错误: 验证码必须为数字.'); } $input = intval($_POST['captcha']); if(!isset($_SESSION['captcha_answer']) || $input !== $_SESSION['captcha_answer']){ return new WP_Error('captcha_error','错误: 验证码错误,请重试.'); } // 验证通过,清理 session unset($_SESSION['captcha_answer'], $_SESSION['captcha_expression']); return $user; } add_filter('authenticate','validate_captcha_on_login',30,3);

建议:保存后先在浏览器无痕模式下测试,确认验证码功能正常后再投入使用

【教程】为WordPress后台登录添加验证码

值得注意的是validate_captcha_on_login部分:

function validate_captcha_on_login($user, $username, $password){ if(!session_id()) session_start(); if(!isset($_POST['captcha']) || !is_numeric($_POST['captcha'])){ return new WP_Error('captcha_error','错误: 验证码必须为数字.'); } $input = intval($_POST['captcha']); if(!isset($_SESSION['captcha_answer']) || $input !== $_SESSION['captcha_answer']){ return new WP_Error('captcha_error','错误: 验证码错误,请重试.'); } // 验证通过,清理 session unset($_SESSION['captcha_answer'], $_SESSION['captcha_expression']); return $user; }

其中的关键位置:

if(!isset($_SESSION['captcha_answer']) || $input !== $_SESSION['captcha_answer'])

这里不区分用户名是否存在,直接判断验证码是否正确。

也就是说:

  • 不管用户名存在与否,只要验证码不对(或者会话里没有答案),就统一返回 “验证码错误”。

  • 即使用户名不存在也返回验证码错误,以达到迷惑攻击者的目的。

各位站长在部署时稍加注意,别被自己的门闩挡在外面了


以下为旧代码,因干扰了 REST API 及环回请求被弃置(拿来做警示展出,勿用)

// 启动 Session function start_session_for_captcha() { if (!session_id()) { @ob_start(); session_start(); } } add_action('init', 'start_session_for_captcha', 1); // 生成验证码 function generate_captcha() { $num1 = rand(10, 99); $num2 = rand(10, 99); $operator = ['+', '-'][rand(0,1)]; if ($operator === '-' && $num1 < $num2) { list($num1, $num2) = [$num2, $num1]; } $_SESSION['captcha_answer'] = ($operator === '+') ? $num1 + $num2 : $num1 - $num2; return "$num1 $operator $num2"; } // 登录表单显示验证码 function add_captcha_to_login_form() { // 只有当 Session 没有答案时生成一次 if (!isset($_SESSION['captcha_answer'])) { $expression = generate_captcha(); } else { // 如果已有答案,显示当前的公式 $answer = $_SESSION['captcha_answer']; $expression = ''; // 为了安全,这里可以保留空,或者生成表达式存储在 $_SESSION['captcha_expression'] } echo "

验证码:" . (isset($_SESSION['captcha_expression']) ? $_SESSION['captcha_expression'] : generate_captcha()) . " = ?

<script> document.getElementById('refresh-captcha').addEventListener('click', function() { const btn = this; btn.style.transition='transform 0.3s'; btn.style.transform='rotate(360deg)'; setTimeout(()=>{btn.style.transform='rotate(0deg)';},300); fetch('" . admin_url('admin-ajax.php') . "?action=refresh_captcha&_=' + new Date().getTime()) .then(r=>r.json()) .then(data=>{ if(data.success){ document.querySelector('#login-captcha label').innerText='验证码:'+data.data.expression+' = ?'; document.querySelector('#captcha').value=''; }else{ alert(data.data || '刷新失败,请重试'); } }).catch(e=>{ console.error('刷新验证码失败:',e); alert('刷新验证码失败,请重试'); }); }); script>"; } add_action('login_form', 'add_captcha_to_login_form'); // AJAX 刷新验证码 function ajax_refresh_captcha() { if (!session_id()) session_start(); $expression = generate_captcha(); $_SESSION['captcha_expression'] = $expression; // 存储公式 wp_send_json_success(['expression'=>$expression]); } add_action('wp_ajax_refresh_captcha', 'ajax_refresh_captcha'); add_action('wp_ajax_nopriv_refresh_captcha', 'ajax_refresh_captcha'); // 登录验证 function validate_captcha_on_login($user,$username,$password){ if(!isset($_POST['captcha']) || !is_numeric($_POST['captcha'])){ return new WP_Error('captcha_error','错误: 验证码必须为数字.'); } $input=intval($_POST['captcha']); if(!isset($_SESSION['captcha_answer']) || $input!==$_SESSION['captcha_answer']){ return new WP_Error('captcha_error','错误: 验证码错误,请重试.'); } unset($_SESSION['captcha_answer'], $_SESSION['captcha_expression']); return $user; } add_filter('authenticate','validate_captcha_on_login',30,3);

作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起
0评论

当前文章无评论,是时候发表评论了
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章

爱似胸奴

Ta还没有介绍自己

关注 打赏
最新文章 热门文章
0
扫一下,分享更方便,购买更轻松