首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 產生數字驗證碼防惡意註冊完整實作教學

     編輯:PHP 相關知識

驗證碼是防禦機器人惡意註冊、暴力破解的基礎防線。本文從零建立一個數字圖形驗證碼系統,涵蓋:GD 繪圖干擾線/噪點、Session 儲存驗證值、前端表單整合、後端驗證邏輯與安全強化。

1. 驗證碼產生器

建立 captcha.php:

<?php
session_start();

// 1. 產生 4 位隨機數字
$code = '';
for ($i = 0; $i < 4; $i++) $code .= mt_rand(0, 9);
// 或直接:$code = (string)mt_rand(1000, 9999);

// 2. 存入 Session 供後續驗證
$_SESSION['captcha_code'] = $code;

// 3. 建立畫布
$width = 100; $height = 36;
$im = imagecreatetruecolor($width, $height);

// 4. 分配顏色
$bg = imagecolorallocate($im, 230, 230, 230); // 淺灰背景
$textColor = imagecolorallocate($im, 0, 0, 0);  // 黑色文字
$noiseColor = imagecolorallocate($im, 150, 150, 150);

// 5. 填充背景
imagefill($im, 0, 0, $bg);

// 6. 繪製干擾線 (3 條)
for ($i = 0; $i < 3; $i++) {
    imageline($im,
        mt_rand(0, $width), mt_rand(0, $height),
        mt_rand(0, $width), mt_rand(0, $height),
        $noiseColor
    );
}

// 7. 繪製干擾點 (50 個)
for ($i = 0; $i < 50; $i++) {
    imagesetpixel($im, mt_rand(0, $width), mt_rand(0, $height), $noiseColor);
}

// 8. 繪製驗證碼文字 (逐字隨機位置)
$fontSize = 5; // 內建字體 1-5
$x = 10;
for ($i = 0; $i < 4; $i++) {
    $y = mt_rand(4, 12);
    imagestring($im, $fontSize, $x, $y, $code[$i], $textColor);
    $x += mt_rand(18, 24); // 字元間距隨機
}

// 9. 輸出圖片
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
?>

2. 註冊表單整合

<form action="register.php" method="post">
    <!-- 其他欄位 -->
    <div>
        <label>驗證碼:</label>
        <input type="text" name="captcha" maxlength="4" required style="width: 80px;">
        <img id="captchaImg" src="captcha.php" alt="點擊更換" style="vertical-align: middle; cursor: pointer;" title="點擊更換">
    </div>
    <button type="submit">註冊</button>
</form>

<script>
// 點擊圖片更換驗證碼
document.getElementById('captchaImg').onclick = function() {
    this.src = 'captcha.php?' + Date.now(); // 防快取
};
</script>

3. 後端驗證邏輯

register.php:

<?php
session_start();

// 1. 基本檢查
if (empty($_POST['captcha'])) {
    exit(json_encode(['ok' => false, 'msg' => '請輸入驗證碼']));
}

// 2. 驗證碼比對 (不區分大小寫,數字無影響)
if (strtolower($_POST['captcha']) !== strtolower($_SESSION['captcha_code'] ?? '')) {
    // 驗證失敗後清除舊碼,防止重試
    unset($_SESSION['captcha_code']);
    exit(json_encode(['ok' => false, 'msg' => '驗證碼錯誤']));
}

// 3. 驗證通過,清除 Session 碼 (一次性使用)
unset($_SESSION['captcha_code']);

// 4. 後續處理註冊邏輯...
// $username = $_POST['username']; ...
// 執行資料庫插入...

echo json_encode(['ok' => true, 'msg' => '註冊成功']);
?>

4. 安全強化建議

  1. 使用 TTF 字體:imagettftext() 搭配扭曲、旋轉,大幅提高機器識別難度。
  2. 加入 Session 鎖定:防止並發請求競態條件。
  3. 限制驗證次數:同一 IP/Session 短時間內失敗 N 次暫時封鎖。
  4. HTTPS 傳輸:防止驗證碼被中間人竊取。
  5. 考慮現代替代方案:Google reCAPTCHA v3 (無感)、hCaptcha、Turnstile,體驗更好且防禦更強。

5. 常見問題排查

  • 圖片顯示亂碼:確保 captcha.php 無任何輸出 (含空白行、BOM) 在 header() 之前,且檔案編碼為 UTF-8 無 BOM。
  • Session 失效:確認所有頁面均在最開頭呼叫 session_start(),且 session.cookie_domain 設定正確。
  • GD 未安裝:執行 php -m | grep gd 檢查,或 phpinfo() 確認。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved