【发布时间】:2016-07-02 19:19:15
【问题描述】:
我有一个 Laravel 应用程序,它使用 Web 服务来验证字段,REST 调用通过 Guzzle 通过 HTTPS。当我通过浏览器发布表单时,一切正常。当我通过 phpunit 运行相同的测试时,Guzzle 失败并显示:
exception 'GuzzleHttp\Exception\RequestException' with message 'cURL error 51: SSL: certificate verification failed (result: 5)
我尝试了什么:
1- 在 Guzzle 之前,我使用了直接向上的 curl,它给出了相同的行为。我尝试使用curl_setopt($curl, CURLOPT_CAINFO, '/path/to/cacert.pem'); 在代码中明确设置cacert,但什么也没做
2- 我尝试(相同的结果)用
将 Guzzle 指向 cacert$response = $client->request('GET', $url, [
'auth' => ['user', 'pass'],
'verify' => '/path/to/cacert.pem'
]);
3- phpinfo 说 Apache 正在使用其本地 curl 和命令行 php 使用不同的,所以我符号链接到 Apache 版本,相同的结果
4- curl.cainfo 和 openssl.cainfo 都已设置
5- /usr/local/etc/openssl/cert.pem 存在
6- 在命令行上将-d openssl.cainfo 传递给 phpunit 没有任何作用
代码:
private function curl_rest_call($url){
// $curl = curl_init() ;
// curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
// curl_setopt($curl, CURLOPT_USERPWD, "user:pass");
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
// curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
// curl_setopt($curl, CURLOPT_CAINFO, '/path/to/cacert.pem');
// curl_setopt($curl, CURLOPT_URL, $url);
// curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// $rest = curl_exec($curl);
// $httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
// curl_close($curl);
// $result = json_decode($rest) ;
// $result->status = $httpStatus ;
// return $result ;
$client = new Guzzle();
$response = $client->request('GET', $url, [
'auth' => ['user', 'pass'],
'verify' => '/path/to/cacert.pem'
]);
$result = json_decode($response->getBody()->getContents()) ;
$result->status = $response->getStatusCode() ;
return $result ;
}
测试:
public function testSuccessfulSignup(){
$this->visit('/free-software')
->type('test@mail.com', 'mail')
->type('Philip', 'first_name')
->type('Fry', 'last_name')
->select('Freelancer', 'profile')
->type('Other', 'industry')
->select('Canada', 'country')
->type('(514) 278-8666', 'phone_number')
->press('Try Harmony Now!')
->seePageIs('/success');
}
【问题讨论】:
-
您为证书检查指定的 PEM 文件很可能不包含您正在连接的站点正在使用的 CA 证书。你能确认它存在于文件中吗?
-
@drew010 是的,它就在那里
-
不是您问题的答案,但我可能会尽量避免首先测试实际调用外部服务。像这样的测试通常(非常)缓慢且脆弱(例如,由于连接问题)导致大量误报。使用存根服务进行功能测试要可靠得多。您仍然可以在验收测试中测试实际功能,例如在你的 UI 中使用 Selenium 驱动的交互。只是出于好奇,您可以发布测试吗?
-
@dbrumann 测试非常简单,我考虑过存根 REST 调用,但它与使用
AppServiceProvider级别的自定义验证器的模型验证相关。 -
嗯,cURL 错误 51 的意思是:
The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK.您在浏览器中访问该站点时是否遇到任何错误? PHP 使用的是什么 cURL 版本,以及 cURL 链接到的 OpenSSL 版本是什么?
标签: laravel ssl curl phpunit guzzle