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

PHP 通過 SMTP 協議驗證郵箱賬號密碼

     編輯:PHP 綜合知識

應用場景

內部系統統一認證,利用現有郵件服務器(如 163、QQ 企業郵箱)驗證用戶身份,無需維護獨立用戶表。

核心實現原理

基於 SMTP 協議的 AUTH LOGIN 機制,通過 fsockopen 建立 TCP 連接,按流程發送命令並解析響應碼:

  1. 連接服務器,等待 220 就緒響應
  2. 發送 HELO,等待 250
  3. 發送 AUTH LOGIN,等待 334 (請求用戶名)
  4. 發送 Base64 編碼用戶名,等待 334 (請求密碼)
  5. 發送 Base64 編碼密碼,等待 235 (認證成功)

完整驗證函數

<?php
/**
 * SMTP 郵箱賬號密碼驗證
 * @param string $email    完整郵箱地址
 * @param string $password 密碼
 * @param string $server   SMTP 服務器地址
 * @param int    $port     端口,默認 25
 * @return bool
 */
function validateSmtpLogin(string $email, string $password, string $server = 'smtp.163.com', int $port = 25): bool {
    $socket = @fsockopen($server, $port, $errno, $errstr, 10);
    if (!$socket) return false;

    // 讀取歡迎信息
    $response = fgets($socket, 512);
    if (strpos($response, '220') !== 0) { fclose($socket); return false; }

    // HELO
    fwrite($socket, "HELO localhost\r\n");
    $response = fgets($socket, 512);
    if (strpos($response, '250') !== 0) { fclose($socket); return false; }

    // AUTH LOGIN
    fwrite($socket, "AUTH LOGIN\r\n");
    $response = fgets($socket, 512);
    if (strpos($response, '334') !== 0) { fclose($socket); return false; }

    // 用戶名
    fwrite($socket, base64_encode($email) . "\r\n");
    $response = fgets($socket, 512);
    if (strpos($response, '334') !== 0) { fclose($socket); return false; }

    // 密碼
    fwrite($socket, base64_encode($password) . "\r\n");
    $response = fgets($socket, 512);
    fclose($socket);

    return strpos($response, '235') === 0;
}

// 使用示例
if (validateSmtpLogin('user@163.com', 'password123')) {
    echo '登錄成功';
    // 設置 Session、生成 Token 等
} else {
    echo '郵箱或密碼錯誤';
}

常見郵件服務器配置

服務商SMTP 服務器端口備註
163/126smtp.163.com25/465/587需開啟 SMTP 服務並設置授權碼
QQ 郵箱smtp.qq.com465/587需使用授權碼,建議 SSL 端口 465
Gmailsmtp.gmail.com465/587需開啟「安全性較低的應用」或應用專用密碼
Outlooksmtp.office365.com587STARTTLS 加密

進階:支持 SSL/TLS 連接

對於 465 端口(隱式 SSL),需使用 ssl:// 前綴:

$socket = @fsockopen('ssl://smtp.qq.com', 465, $errno, $errstr, 15);

對於 587 端口(顯式 STARTTLS),建議改用 PHPMailer 或 SwiftMailer 等成熟庫,手動實現 STARTTLS 較為複雜。

安全建議

  • 生產環境務必使用加密連接(465 或 587+STARTTLS),防止密碼明文傳輸。
  • 限制驗證頻率,防止暴力破解。
  • 記錄審計日志(IP、郵箱、時間、結果),不記錄密碼。
  • 考慮使用 OAuth2.0(Google、Microsoft 支持)替代密碼認證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved