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

PHP 實作驗證碼 (CAPTCHA) 完整教學

     編輯:PHP 相關知識

PHP 實作驗證碼 (CAPTCHA) 完整教學

驗證碼用於區分人類與自動化腳本,保護登入、註冊、留言等表單免受暴力破解與垃圾內容攻擊。本文示範基於 GD 庫生成圖形驗證碼、Session 儲存、前端整合與驗證的完整流程。

1. 生成驗證碼圖片 captcha.php

<?php
session_start();

// 1. 設定圖片尺寸
$width = 120; $height = 40;
$image = imagecreatetruecolor($width, $height);

// 2. 分配顏色
$bg = imagecolorallocate($image, 240, 240, 240); // 淺灰背景
$textColor = imagecolorallocate($image, 0, 0, 0);
$noiseColor = imagecolorallocate($image, 180, 180, 180);

// 3. 填充背景
imagefilledrectangle($image, 0, 0, $width, $height, $bg);

// 4. 產生隨機驗證碼 (4 位數字 + 字母)
$chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'; // 排除易混淆字元
$code = '';
for ($i = 0; $i < 4; $i++) {
    $code .= $chars[mt_rand(0, strlen($chars) - 1)];
}
$_SESSION['captcha_code'] = $code; // 存入 Session

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

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

// 7. 繪製驗證碼文字 (隨機位置、旋轉、字體大小)
$fontSize = 20;
for ($i = 0; $i < 4; $i++) {
    $x = 20 + $i * 24 + mt_rand(-3, 3);
    $y = 28 + mt_rand(-3, 3);
    $angle = mt_rand(-15, 15);
    imagettftext($image, $fontSize, $angle, $x, $y, $textColor, __DIR__ . '/fonts/arial.ttf', $code[$i]);
}

// 8. 輸出 PNG
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
?>

2. 前端整合

<form action="login_check.php" method="post">
    <input type="text" name="username" placeholder="帳號" required>
    <input type="password" name="password" placeholder="密碼" required>
    <input type="text" name="captcha" placeholder="驗證碼" maxlength="4" required>
    <img src="captcha.php" id="captchaImg" alt="驗證碼" style="vertical-align:middle; cursor:pointer;" title="點擊更換">
    <button type="submit">登入</button>
</form>
<script>
document.getElementById('captchaImg').onclick = function() {
    this.src = 'captcha.php?' + Date.now(); // 加時間戳防快取
};
</script>

3. 後端驗證 login_check.php

<?php
session_start();

$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$captcha = strtoupper($_POST['captcha'] ?? '');

if (empty($captcha) || $captcha !== $_SESSION['captcha_code']) {
    // 驗證碼錯誤
    $_SESSION['error'] = '驗證碼錯誤';
    header('Location: login.php');
    exit;
}

// 驗證碼正確,清除避免重複使用
unset($_SESSION['captcha_code']);

// 繼續帳號密碼驗證...
// $user = $db->findUser($username);
// if ($user && password_verify($password, $user['password_hash'])) { ... }
?>

4. 進階強化方向

  • 字體多樣化:準備多種 TTF 字體隨機選用,增加辨識難度。
  • 扭曲/波紋效果:使用 imagecopyresampled 配合正弦波位移,或套用 imagick 的 distortImage。
  • 語音驗證碼:為視障使用者提供音檔播放 (需 TTS 服務)。
  • 行為驗證:整合 Google reCAPTCHA v3 / hCaptcha / Geetest,無感知風險評分。
  • 限流:同一 IP 短時間請求驗證碼次數過多時暫時封鎖。

常見錯誤避坑

  1. Session 未啟動:session_start() 必須在任何輸出前呼叫,且生成圖片與驗證頁面都要呼叫。
  2. 編碼不一致:驗證碼字元集與前端輸入編碼必須一致 (皆用 UTF-8)。
  3. 快取問題:圖片 URL 必須加隨機查詢字串 (?t=timestamp) 避免瀏覽器快取舊圖。
  4. GD 未安裝:php -m | grep gd 確認,Ubuntu apt install php-gd。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved