随记 | 注册验证码

这几天经常有不明来路的机器人注册账号,于是增加了注册时的验证码。

启用 Session 会话

WordPress 核心在未登录状态下通常不开启 PHP 原生 Session,但我们需要它来在服务器端存储生成的验证码,以便在提交表单时进行比对。

if (!session_id()) {
    session_start();
}

初始化 $_SESSION 数组。

验证拦截

在数据写入数据库之前,必须拦截注册流程。如果验证码错误,阻止 register_new_user 函数的执行。

在 case ‘register’ : 代码块 if($http_post) 内,处理用户名和邮箱获取后。

if (!isset($_SESSION['wp_register_captcha']) || !isset($_POST['captcha_code']) || strtoupper($_POST['captcha_code']) != = $_SESSION['wp_register_captcha']) {
    $errors = new WP_Error('captcha_error', __('<strong>Error</strong>: Incorrect verification code.'));
} else {
    $errors = register_new_user($user_login, $user_email);
}
  1. 检查 $_SESSION[‘wp_register_captcha’] 是否存在。
  2. 检查用户提交的 $_POST[‘captcha_code’] 是否存在。
  3.  使用 strtoupper() 将用户输入转为大写,与 Session 中的验证码进行恒等比较。
  • 如果比对失败,实例化一个新的 WP_Error 对象,错误代码为 captcha_error。这会中断后续流程,并将错误信息传回前端显示。
  • 如果比对成功,才执行原有的 register_new_user( $user_login, $user_email )。

图片生成

直接在 wp-login.php 内部生成图片流,并以 Base64 编码内嵌到 HTML 中。

定义字符集 ABCDEFGHJKLMNPQRSTUVWXYZ23456789 ,移除了 0, O, 1, I 等容易混淆的字符,用 str_shuffle 打乱字符集,取前 5 位为验证码,将结果存入 $_SESSION[‘wp_register_captcha’] 。

用 PHP 的 GD 图形库绘制图片。

  1. 创建画布: imagecreatetruecolor(100, 36) 创建真彩色画布。
  2. 噪点与干扰线:
    • 噪点: 循环 1000 次,随机在画布上画点 (imagesetpixel)。
    • 干扰线: 循环 20 次,随机画横跨画布的线条 (imageline)。
  3. 文字写入: 使用 imagestring 将随机字符写入图片。
  4. 居中计算: 通过 imagefontwidth 和 imagefontheight 动态计算文字坐标 (x, y),确保文字居中。
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$captcha_code = substr(str_shuffle($chars), 0, 5);
$_SESSION['wp_register_captcha'] = $captcha_code;

$captcha_image_html = '';

// 尝试使用 GD 库生成图片验证码
if (extension_loaded('gd') && function_exists('imagecreatetruecolor')) {
    $width = 100;
    $height = 36;
    $im = imagecreatetruecolor($width, $height);

    // 颜色定义
    $bg = imagecolorallocate(
        $im,
        rand(230, 255),
        rand(230, 255),
        rand(230, 255));
    $text_color = imagecolorallocate(
        $im,
        rand(100, 200),
        rand(100, 200),
        rand(100, 200));
    $line_color = imagecolorallocate(
        $im,
        rand(150, 200),
        rand(150, 200),
        rand(150, 200));
    $pixel_color = imagecolorallocate(
        $im,
        rand(180, 220),
        rand(180, 220),
        rand(180, 220));

    imagefill($im, 0, 0, $bg);

    // 干扰点
    for ($i = 0; $i < 1000; $i++) {
        imagesetpixel($im, rand(0, $width), rand(0, $height), $pixel_color);
    }

    // 干扰线
    for ($i = 0; $i < 20; $i++) {
        imageline($im, rand(0, $width), rand(0, $height), rand(0, $width), rand(0, $height), $line_color);
    }

    // 写入文字
    $font_size = 5;
    $x = ($width - (imagefontwidth($font_size) * strlen($captcha_code))) / 2;
    $y = ($height - imagefontheight($font_size)) / 2;
    imagestring($im, $font_size, $x, $y, $captcha_code, $text_color);

    // 输出图片流并转为 Base64
    ob_start();
    imagepng($im);
    $image_data = ob_get_clean();
    imagedestroy($im);

    $base64_src = 'data:image/png;base64,'.base64_encode($image_data);
    $captcha_image_html = '<img src="'.$base64_src.'" alt="验证码" style="vertical-align:middle; border: 1px solid #ddd; cursor:pointer;" title="Verification Code" />';
} else {
    // 如果不支持 GD 库
    $captcha_image_html = '<span style="background:#eee; padding:5px 10px; font-weight:bold; letter-spacing: 3px; border:1px solid #ccc;">'.esc_html($captcha_code).'</span>';
}

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇