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

PHP 對接容聯云通訊短信驗證碼接口完整實現

     編輯:PHP 綜合知識

準備工作

  1. 註冊 容聯云通訊 開發者賬號
  2. 創建應用,獲取:Account SID、Auth Token、App ID
  3. 配置短信模板(如驗證碼模板 ID=1,內容:您的驗證碼是{1},{2}分鐘內有效)
  4. 測試環境需在控制台添加測試手機號

目錄結構

project/
├── includes/
│   └── rly_message/
│       ├── rest.app.php   # SDK 核心類
│       └── test.app.php   # 控制器示例
└── templates/
    └── test.html          # 前端頁面

核心 SDK (rest.app.php)

<?php
class RestApp {
    private $AccountSid, $AccountToken, $AppId;
    private $ServerIP = 'app.cloopen.com', $ServerPort = '8883', $SoftVersion = '2013-12-26';
    private $Batch, $BodyType = 'json', $enabeLog = true, $Filename = __DIR__.'/sms.log';

    public function __construct($ServerIP, $ServerPort, $SoftVersion) {
        $this->ServerIP = $ServerIP;
        $this->ServerPort = $ServerPort;
        $this->SoftVersion = $SoftVersion;
        $this->Batch = date('YmdHis');
        $this->Handle = fopen($this->Filename, 'a');
    }

    public function setAccount($sid, $token) {
        $this->AccountSid = $sid; $this->AccountToken = $token;
    }
    public function setAppId($appId) { $this->AppId = $appId; }

    /** 發送模板短信
     * @param string $to 手機號,多號碼英文逗號分隔
     * @param array  $datas 模板變量,如 ['123456', '5']
     * @param string $tempId 模板 ID
     */
    public function sendTemplateSMS($to, array $datas, $tempId) {
        // 1. 參數校驗
        if (!$this->AccountSid || !$this->AccountToken || !$this->AppId) {
            return (object)['statusCode'=>'172006', 'statusMsg'=>'配置缺失'];
        }

        // 2. 構建請求體
        $dataStr = '';
        foreach ($datas as $v) $dataStr .= "$v";
        $body = "<TemplateSMS><to>$to</to><appId>$this->AppId</appId><templateId>$tempId</templateId><datas>$dataStr</datas></TemplateSMS>";

        // 3. 鑒權簽名
        $sig = strtoupper(md5($this->AccountSid . $this->AccountToken . $this->Batch));
        $url = "https://$this->ServerIP:$this->ServerPort/$this->SoftVersion/Accounts/$this->AccountSid/SMS/TemplateSMS?sig=$sig";
        $auth = base64_encode("$this->AccountSid:$this->Batch");
        $headers = [
            "Accept:application/$this->BodyType",
            "Content-Type:application/$this->BodyType;charset=utf-8",
            "Authorization:$auth"
        ];

        // 4. 發送請求
        $result = $this->curlPost($url, $body, $headers);
        $this->log("REQUEST: $url\n$body\nRESPONSE: $result");

        // 5. 解析響應
        $obj = simplexml_load_string(trim($result));
        if ($obj && $obj->statusCode == '0') {
            $obj->TemplateSMS = $obj->templateSMS; // 統一屬性名
        }
        return $obj;
    }

    private function curlPost($url, $data, $headers) {
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $data,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_TIMEOUT => 30,
        ]);
        $ret = curl_exec($ch);
        if ($ret === false) {
            $ret = '<?xml version="1.0"?><Response><statusCode>172001</statusCode><statusMsg>網絡錯誤</statusMsg></Response>';
        }
        curl_close($ch);
        return $ret;
    }

    private function log($msg) {
        if ($this->enabeLog) fwrite($this->Handle, date('Y-m-d H:i:s')." $msg\n");
    }
}

控制器示例 (test.app.php)

<?php
require_once __DIR__.'/rest.app.php';

$accountSid  = 'YOUR_ACCOUNT_SID';
$accountToken = 'YOUR_AUTH_TOKEN';
$appId       = 'YOUR_APP_ID';
$serverIP    = 'app.cloopen.com'; // 生產環境
$serverPort  = '8883';
$softVersion = '2013-12-26';

$phone = $_GET['phone'] ?? '';
if (!$phone) exit(json_encode(['code'=>400, 'msg'=>'手機號不能為空']));

$rest = new RestApp($serverIP, $serverPort, $softVersion);
$rest->setAccount($accountSid, $accountToken);
$rest->setAppId($appId);

// 模板 ID=1,變量:驗證碼、有效分鐘數
$code = rand(100000, 999999);
$result = $rest->sendTemplateSMS($phone, [$code, '5'], '1');

header('Content-Type: application/json; charset=utf-8');
if ($result->statusCode == '0') {
    // TODO: 將 $code 存入 Redis/Session,設置 5 分鐘過期,供驗證接口比對
    echo json_encode(['code'=>200, 'msg'=>'發送成功', 'sid'=>$result->TemplateSMS->smsMessageSid]);
} else {
    echo json_encode(['code'=>500, 'msg'=>$result->statusMsg, 'errCode'=>$result->statusCode]);
}

前端交互 (test.html + JS)

<!DOCTYPE html><html><head><meta charset="utf-8"><title>短信驗證碼演示</title></head><body>
<div style="max-width:400px;margin:40px auto;padding:20px;border:1px solid #eee;border-radius:8px">
  <h3 style="text-align:center">短信驗證碼</h3>
  <div><input type="tel" id="phone" placeholder="請輸入手機號" style="width:70%">
    <button id="btnSend" style="width:28%">獲取驗證碼</button></div>
  <div style="margin-top:15px"><input type="text" id="code" placeholder="輸入驗證碼" style="width:70%"></div>
  <div style="margin-top:15px;text-align:center"><button id="btnVerify">驗證</button></div>
  <p id="tip" style="color:#666;text-align:center;margin-top:10px"></p>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
let countdown = 0;
$('#btnSend').click(function(){
  const phone = $('#phone').val().trim();
  if (!/^1[3-9]\d{9}$/.test(phone)) return alert('手機號格式錯誤');
  $(this).prop('disabled', true);
  $.getJSON('test.app.php', {phone}, function(res){
    if (res.code === 200) {
      countdown = 60;
      const timer = setInterval(() => {
        $('#btnSend').text(countdown + 's 重發');
        if (--countdown <= 0) { clearInterval(timer); $('#btnSend').prop('disabled', false).text('獲取驗證碼'); }
      }, 1000);
      $('#tip').css('color','green').text('驗證碼已發送,請查收');
    } else {
      $('#btnSend').prop('disabled', false);
      $('#tip').css('color','red').text(res.msg);
    }
  });
});
$('#btnVerify').click(function(){
  const code = $('#code').val().trim();
  if (!code) return alert('請輸入驗證碼');
  // 此處應調用後端驗證接口比對 Redis/Session 中的碼
  alert('演示模式:假設驗證通過,實際請對接後端驗證邏輯');
});
</script>
</body></html>

生產環境關鍵補充

  1. 驗證碼存儲:Redis SET sms:code:{phone} {code} EX 300,驗證時 GET 比對並 DEL 防暴力破解。
  2. 頻率限制:同一 IP/手機號 60s 內僅允許 1 次,Redis SET sms:lock:{phone} 1 EX 60 NX。
  3. 異常重試:網絡錯誤(172001)可指數退避重試 3 次,記錄失敗日誌告警。
  4. HTTPS 證書:生產環境請配置 CURLOPT_CAINFO 指向有效 CA 憑證,勿關閉驗證。
  5. 模板變量順序:嚴格按模板佔位符順序傳遞 $datas 數組。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved