在開發 QQ 登入回調功能時,使用 file_get_contents() 無法獲取 HTTPS 接口回應,改用 cURL 後拋出 SSL certificate verify failed 錯誤。這是因為 PHP 預設開啟了嚴格的 SSL 證書驗證,而開發/測試環境常缺少有效的 CA 憑證鏈。
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://graph.qq.com/oauth2.0/me?access_token=...');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 關鍵兩行:跳過證書驗證
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
curl_close($ch);
CURLOPT_SSL_VERIFYPEER = false:不驗證伺服器證書是否由受信 CA 簽發。CURLOPT_SSL_VERIFYHOST = false:不檢查證書中的 Common Name (CN) 是否與請求主機名匹配(2 為嚴格檢查,1 僅檢查存在性,0 完全跳過)。上述方案僅適用於開發調試,**嚴禁用於生產環境**,否則會遭受中間人攻擊。正確做法:
php.ini:curl.cainfo = "/path/to/cacert.pem"
openssl.cafile = "/path/to/cacert.pem"
或在代碼中動態指定:
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem');
curl_setopt($ch, CURLOPT_CAPATH, '/path/to/certs_dir/');
CURLOPT_HTTPHEADER => ['Expect:'] 的誤區網上流傳設置 Expect: 可解決 SSL 錯誤,實測**無效**。該頭部用於控制 HTTP/1.1 的 100 Continue 行為,與 SSL 層無關。
開發期用 VERIFYPEER=false 快速跑通流程;上線前務必配置有效 CA 憑證,確保傳輸層安全。記得在代碼中加上環境判斷,避免誤上生產:
if (APP_ENV !== 'production') {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}