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

PHP 生成 PNG 驗證碼完整實現:思路、代碼與安全加固

     編輯:PHP 相關知識

PHP 圖形驗證碼生成實戰指南

圖形驗證碼是防止機器人惡意註冊、暴力破解的基礎防線。本文詳細講解基於 GD 庫生成 PNG 驗證碼的完整流程,含干擾線、噪點、字符扭曲等反識別技術,並給出生產環境安全建議。

一、實現思路(8 步驟)

  1. 創建畫布:imagecreate() 或 imagecreatetruecolor()
  2. 分配背景色:imagecolorallocate()(首次調用即填充背景)
  3. 設置字體顏色與 TTF 字體路徑
  4. 生成隨機字符串(數字+大寫字母)
  5. 逐字符繪製:imagettftext() 隨機旋轉角度、隨機 Y 軸偏移
  6. 繪製干擾線:imageline() 隨機顏色、位置
  7. 繪製噪點:imagesetpixel()
  8. 輸出 PNG 頭並輸出圖像:header('Content-Type: image/png') + imagepng()
  9. 銷毀圖像資源:imagedestroy()

二、完整代碼實現 (authcode.php)

<?php
session_start();
header('Content-Type: image/png');

// 1. 畫布尺寸
$width  = 130;
$height = 45;
$im = imagecreatetruecolor($width, $height);

// 2. 隨機背景色 (較淺)
$bg = imagecolorallocate($im, rand(180, 255), rand(180, 255), rand(180, 255));
imagefill($im, 0, 0, $bg);

// 3. 字體顏色 (較深) 與字體文件
$fontColor = imagecolorallocate($im, rand(0, 100), rand(0, 100), rand(0, 100));
$fontFile  = __DIR__ . '/fonts/arial.ttf'; // 需確保字體文件存在

// 4. 生成 4 位隨機驗證碼
$code = '';
for ($i = 0; $i < 4; $i++) {
    // 數字 0-9 或 大寫字母 A-Z
    $char = chr(rand(0, 1) ? rand(48, 57) : rand(65, 90));
    $code .= $char;
    
    // 5. 繪製字符:隨機角度 ±25°,X 間距 30px,Y 隨機 30-35px
    $angle = rand(-25, 25);
    $x = 10 + $i * 28;
    $y = rand(30, 38);
    imagettftext($im, 24, $angle, $x, $y, $fontColor, $fontFile, $char);
}

// 存入 Session (供驗證時比對)
$_SESSION['authcode'] = strtolower($code); // 不區分大小寫

// 6. 干擾線 (6-10 條)
for ($i = 0; $i < rand(6, 10); $i++) {
    $lineColor = imagecolorallocate($im, rand(100, 200), rand(100, 200), rand(100, 200));
    imageline($im, rand(0, $width), 0, rand(0, $width), $height, $lineColor);
}

// 7. 噪點 (100-200 個)
for ($i = 0; $i < rand(100, 200); $i++) {
    $noiseColor = imagecolorallocate($im, rand(0, 255), rand(0, 255), rand(0, 255));
    imagesetpixel($im, rand(0, $width), rand(0, $height), $noiseColor);
}

// 8. 輸出與銷毀
imagepng($im);
imagedestroy($im);
?>

三、前端調用示例

<img id="captcha" src="authcode.php" alt="驗證碼" style="cursor:pointer;vertical-align:middle" onclick="this.src='authcode.php?'+Math.random()" />
<input type="text" name="captcha_input" placeholder="點擊圖片換一張" />

四、後端驗證邏輯

<?php
session_start();
if (strtolower($_POST['captcha_input']) !== ($_SESSION['authcode'] ?? '')) {
    die('驗證碼錯誤');
}
// 通過後清除,防止重放
unset($_SESSION['authcode']);
?>

五、安全加固與最佳實踐

風險點對策
OCR 識別破解增加字符扭曲、重疊、波浪紋理、背景圖片干擾;或升級為行為驗證碼(滑塊/點選)
Session 劫持/重放驗證後立即銷毀 Session 驗證碼;限制驗證碼有效期(如 5 分鐘)
暴力遍歷限制同 IP 刷新/驗證頻率(Redis 計數器);失敗 N 次鎖定
字體文件缺失部署時打包 TTF 字體;檢查 imagettftext 返回值
內存洩漏必須調用 imagedestroy();大並發下考慮緩存生成的圖片

六、進階方案推薦

  • Gregwar/Captcha:Composer 包,API 簡潔,支援多種干擾模式 composer require gregwar/captcha
  • Google reCAPTCHA v3:無感驗證,基於行為評分,極高安全性
  • Geetest / 騰訊防水墻:國內主流行為驗證服務,支援滑塊、點選、無感模式
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved