googleads / googleads-php-lib

Google Ad Manager SOAP API Client Library for PHP
Apache License 2.0
655 stars 770 forks source link

cURL error 60: SSL certificate problem with soapSettings SSL check disabled #208

Closed ederbarradas closed 7 years ago

ederbarradas commented 7 years ago

I get this issue whenever I try to make a call to the services.

RequestException in xxxxxxxxxxx\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php line 187: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

I disabled the SSL check by creating a $soapSettings object like this $soapSettings= (new SoapSettingsBuilder()) ->disableSslVerify() ->build(); ...and then add it on the dfpSession object using withSoapSettings($soapSettings), but it seems that the SSL check doesn't get all the way to the guzzle library (which i believe is the one causing problems)

vtsao commented 7 years ago

Hey @ederbarradas which service are you trying to make an API call to? Guzzle is only used for non-SOAP calls in this library (so things like AdWords reporting and parts of batch jobs).

SOAP API calls in this library use PHP's native SOAP toolkit, which doesn't use Guzzle. So disabling SSL for SOAP won't affect Guzzle in this library.

It looks like it may be an issue with your Curl installation and its certificates, but I'll need more information on which service you're trying to call.

Thanks, Vincent

ederbarradas commented 7 years ago

Hi Vincent,

I make a lot of request to different service on my process, but the first call that I made (and the first call to fail) is getCurrentNetwork() from the Network Service.

Now, I'm pretty sure the issue is Guzzle the one with the issue. I went to vendor/guzzlehttp/guzzle/src/Client.php and hardcoded 'verify' => false. That did the trick. I'm able to run the whole process from start to end, calling Network, Inventory, LineItem and other services, with no problems.

So, if disabling SSL check from SOAP API won't affect Guzzle, how can I disable the Guzzle SSL check in your library?

Thanks, Eder

vtsao commented 7 years ago

In this library Guzzle is only used with AdWords reporting or parts of batch jobs, and DFP report downloads.

In all those utils, you can specify a custom HTTP client to use, which you can configure without SSL (we don't have convenience options that wrap Guzzle client options). Although it is not recommended to disable SSL on your calls.

To see if it's a Curl configuration issue on your end, I would recommend writing some test code to use just Guzzle (and not this ads PHP client library) with SSL enabled to see if the same error exists. If the same error crops up, it's likely to do with your system's certificates (i.e., maybe Curl doesn't find them or they are out of date or something).

Let me know.

Thanks, Vincent

vtsao commented 7 years ago

@ederbarradas Sorry I missed that you're using DFP (and not AdWords) - can you confirm?

Also I need some more information from you - are you getting this error when making any call to the DFP API? Can you send me a full stacktrace?

Thanks, Vincent

vtsao commented 7 years ago

Hi @ederbarradas let me know if you're still having issues. I'll close this for now, feel free to re-open. Thanks.

ederbarradas commented 7 years ago

Hey Vincent,

Sorry I couldn't answer before, it's been a couple of busy days.

Like I said, I'm using DFP API and getCurrentNetwork() from the Network service fails. It that process I never make a call to the Report service at all.

Here's the complete Laravel trace:

in CurlFactory.php line 187
at CurlFactory::createRejection(object(EasyHandle), array('errno' => '60', 'error' => 'SSL certificate problem: unable to get local issuer certificate', 'url' => 'https://www.googleapis.com/oauth2/v4/token', 'content_type' => null, 'http_code' => '0', 'header_size' => '0', 'request_size' => '0', 'filetime' => '-1', 'ssl_verify_result' => '0', 'redirect_count' => '0', 'total_time' => '0.047', 'namelookup_time' => '0.031', 'connect_time' => '0.031', 'pretransfer_time' => '0', 'size_upload' => '0', 'size_download' => '0', 'speed_download' => '0', 'speed_upload' => '0', 'download_content_length' => '-1', 'upload_content_length' => '-1', 'starttransfer_time' => '0', 'redirect_time' => '0', 'redirect_url' => '', 'primary_ip' => '216.58.216.10', 'certinfo' => array(), 'primary_port' => '443', 'local_ip' => '192.168.96.215', 'local_port' => '52501')) in CurlFactory.php line 150
at CurlFactory::finishError(object(CurlHandler), object(EasyHandle), object(CurlFactory)) in CurlFactory.php line 103
at CurlFactory::finish(object(CurlHandler), object(EasyHandle), object(CurlFactory)) in CurlHandler.php line 43
at CurlHandler->__invoke(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false)) in Proxy.php line 28
at Proxy::GuzzleHttp\Handler\{closure}(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false)) in Proxy.php line 51
at Proxy::GuzzleHttp\Handler\{closure}(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false)) in PrepareBodyMiddleware.php line 72
at PrepareBodyMiddleware->__invoke(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false)) in Middleware.php line 30
at Middleware::GuzzleHttp\{closure}(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false)) in RedirectMiddleware.php line 68
at RedirectMiddleware->__invoke(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false)) in Middleware.php line 59
at Middleware::GuzzleHttp\{closure}(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false)) in HandlerStack.php line 67
at HandlerStack->__invoke(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false)) in Client.php line 268
at Client->transfer(object(Request), array('synchronous' => true, 'handler' => object(HandlerStack), 'allow_redirects' => array('max' => '5', 'protocols' => array('http', 'https'), 'strict' => false, 'referer' => false, 'track_redirects' => false), 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false, '_conditional' => array('User-Agent' => 'GuzzleHttp/6.2.0 curl/7.30.0 PHP/5.5.9'))) in Client.php line 98
at Client->sendAsync(object(Request), array('synchronous' => true)) in Client.php line 104
at Client->send(object(Request), array()) in Guzzle6HttpHandler.php line 33
at Guzzle6HttpHandler->__invoke(object(Request)) in OAuth2.php line 431
at OAuth2->fetchAuthToken(null) in UserRefreshCredentials.php line 89
at UserRefreshCredentials->fetchAuthToken() in OAuth2TokenRefresher.php line 63
at OAuth2TokenRefresher->getOrFetchAccessToken(object(UserRefreshCredentials)) in DfpHeaderHandler.php line 77
at DfpHeaderHandler->generateHttpHeaders(object(DfpSession)) in AdsSoapClient.php line 99
at AdsSoapClient->__soapCall('getCurrentNetwork', array(array())) in NetworkService.php line 95
at NetworkService->getCurrentNetwork() in DfpApi.php line 244
at DfpApi->createAdUnit('OMG Ultimate Test 20170111_194111') in DfpApi.php line 92
at DfpApi->createDfpSetup('OMG Ultimate Test 20170111_194111', '401220245') in DfpApi.php line 67
at DfpApi->test() in TestController.php line 23
at TestController->index()
at call_user_func_array(array(object(TestController), 'index'), array()) in Controller.php line 80
at Controller->callAction('index', array()) in ControllerDispatcher.php line 146
at ControllerDispatcher->call(object(TestController), object(Route), 'index') in ControllerDispatcher.php line 94
at ControllerDispatcher->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
at Pipeline->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in ControllerDispatcher.php line 96
at ControllerDispatcher->callWithinStack(object(TestController), object(Route), object(Request), 'index') in ControllerDispatcher.php line 54
at ControllerDispatcher->dispatch(object(Route), object(Request), 'App\Http\Controllers\TestController', 'index') in Route.php line 174
at Route->runController(object(Request)) in Route.php line 140
at Route->run(object(Request)) in Router.php line 724
at Router->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Authenticate.php line 28
at Authenticate->handle(object(Request), object(Closure), 'web')
at call_user_func_array(array(object(Authenticate), 'handle'), array(object(Request), object(Closure), 'web')) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in VerifyCsrfToken.php line 64
at VerifyCsrfToken->handle(object(Request), object(Closure))
at call_user_func_array(array(object(VerifyCsrfToken), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ShareErrorsFromSession.php line 49
at ShareErrorsFromSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(ShareErrorsFromSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StartSession.php line 64
at StartSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(StartSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
at AddQueuedCookiesToResponse->handle(object(Request), object(Closure))
at call_user_func_array(array(object(AddQueuedCookiesToResponse), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in EncryptCookies.php line 59
at EncryptCookies->handle(object(Request), object(Closure))
at call_user_func_array(array(object(EncryptCookies), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in VerifyCsrfToken.php line 64
at VerifyCsrfToken->handle(object(Request), object(Closure))
at call_user_func_array(array(object(VerifyCsrfToken), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ShareErrorsFromSession.php line 49
at ShareErrorsFromSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(ShareErrorsFromSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StartSession.php line 64
at StartSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(StartSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
at AddQueuedCookiesToResponse->handle(object(Request), object(Closure))
at call_user_func_array(array(object(AddQueuedCookiesToResponse), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in EncryptCookies.php line 59
at EncryptCookies->handle(object(Request), object(Closure))
at call_user_func_array(array(object(EncryptCookies), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Router.php line 726
at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 699
at Router->dispatchToRoute(object(Request)) in Router.php line 675
at Router->dispatch(object(Request)) in Kernel.php line 246
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Debugbar.php line 51
at Debugbar->handle(object(Request), object(Closure))
at call_user_func_array(array(object(Debugbar), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 44
at CheckForMaintenanceMode->handle(object(Request), object(Closure))
at call_user_func_array(array(object(CheckForMaintenanceMode), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Kernel.php line 132
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 99
at Kernel->handle(object(Request)) in index.php line 54
vtsao commented 7 years ago

Ah okay I forgot that we use Guzzle for refreshing the OAuth2 access token as well, which is why you're seeing these errors if there's an issue with your system certificates.

I filed #216 to track adding a hook to set the Guzzle client being used for these OAuth2 access token calls.

However, I still recommend you look into your system's certs as disabling SSL in a production environment is not recommended.