SSL error in CURL call to Twitter API

2019-08-21 10:26发布

问题:

Below is some code of my controller (dont worry, de keys are fake). Im using the ZendService\Twitter\Twitter module. Almost everything is working only the last error is a bit strange and i can not figure it out:

Unable to enable crypto on TCP connection api.twitter.com: make sure the "sslcafile" or "sslcapath" option are properly set for the environment.

As you can see i the code below of my controller, you can see that both the Verify of Peer and Host are set to false. The adapter is already set to Curl instead of HTTP.

<?php

namespace Twitter\Controller;

use QDCore\Controller\AbstractController;
use Zend\Mvc\MvcEvent;
use Zend\View\Model\JsonModel;
use ZendService\Twitter\Twitter;

class GetController extends AbstractController
{

    protected $instance;

    public function onDispatch(MvcEvent $e)
    {
        $config = array(
            'access_token' => array(
                'token' => '1024003resagsDQGyVC5YZ23423PpBNOwefS',
                'secret' => 'oES8Jergewagewahsh2hTqrYGDJo',
            ),
            'oauth_options' => array(
                'consumerKey' => 'QY360Nersehr234gg4aV2pw',
                'consumerSecret' => 'eEfgdagewa0Hkt4z6nCqHPY1M4wwuubY',
            ),
            'username' => 'myusername',
            'http_client_options' => array(
                'adapter' => 'Zend\Http\Client\Adapter\Curl',
                'curloptions' => array(
                    CURLOPT_SSL_VERIFYHOST => false,
                    CURLOPT_SSL_VERIFYPEER => false,
                ),
            ),
        );
        $this->instance = new Twitter($config);
        return parent::onDispatch($e);
    }


    public function indexAction()
    {
        $result = new JsonModel(array('message' => 'No valid function call made'));
        return $result;
    }

    public function usertimelineAction()
    {
        $options = array(
            'user_id' => 'myaccountname',
            'count' => 30,
        );
        $twitter = new Twitter($options);
        $response = $twitter->statuses->userTimeline();
        var_dump($response);
        die;
        return new JsonModel($response);
    }
}

Hope that someone has an idea on how to fix it. My main domain is not running on SSL and is not going to be.

Thanks

回答1:

NEVER set verify host or peer verification to false, unless you know what you are doing!

You have to point curl to your certification bundle. For Linux (Debian based systems) that is etc/ssl/certs. You could set that as "sslcapath" variable:

'http_client_options' => array(
    'adapter' => 'Zend\Http\Client\Adapter\Curl',
    'curloptions' => array(
        'sslcapath' => '/etc/ssl/certs',
    ),
),

Because the path varies between systems, it's good to have it as an option set in your config/autoload/global.php file which users could change with a local.php configuration. In your config:

'http_client' => array(
    'options' => array(
        'sslcapath' => '/etc/ssl/certs',
    ),
),

Then your code becomes:

public function onDispatch(MvcEvent $e)
{
    $app = $e->getApplication();
    $sm  = $app->getServiceManager();
    $cnf = $sm->get('Config');

    $config = array(
        'access_token' => array(
            'token' => '1024003resagsDQGyVC5YZ23423PpBNOwefS',
            'secret' => 'oES8Jergewagewahsh2hTqrYGDJo',
        ),
        'oauth_options' => array(
            'consumerKey' => 'QY360Nersehr234gg4aV2pw',
            'consumerSecret' => 'eEfgdagewa0Hkt4z6nCqHPY1M4wwuubY',
        ),
        'username' => 'myusername',
        'http_client_options' => array(
            'adapter' => 'Zend\Http\Client\Adapter\Curl',
            'curloptions' => $cnf['http_client']['options'],
        ),
    );
    $this->instance = new Twitter($config);
    return parent::onDispatch($e);
}


回答2:

I had the same exact problem and found this on Google. I understood I should either disable CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER or specify the correct path to the local certificates, but didn't know how to do that.

This answer has helped me a lot:

$config = array(
    'callbackUrl' => 'http://example.com/callback.php',
    'siteUrl' => 'http://twitter.com/oauth',
    'consumerKey' => 'myConsumerKey',
    'consumerSecret' => 'myConsumerSecret'
);
$consumer = new ZendOAuth\Consumer($config);

// this is the key:
$adapter = new \Zend\Http\Client\Adapter\Curl();
$adapter = $adapter->setCurlOption(CURLOPT_SSL_VERIFYHOST, false);
$adapter = $adapter->setCurlOption(CURLOPT_SSL_VERIFYPEER, false);
$httpClient = $consumer->getHttpClient();
$httpClient->setAdapter($adapter);

// now finally fetch a request token
$token = $consumer->getRequestToken();