Question

I'm trying to connect to the Twitter api server to make an "Application-only Autentication". I don't care any other way to connect to Twitter. I need this specific method.

I need to go from localhost through my corporation's proxy to api.twitter.com which needs ssl

Following the instruction of this twitter developer's page https://dev.twitter.com/docs/auth/application-only-auth, i tried with:

cUrl:

try {
    $ch = curl_init();    
    curl_setopt($ch, CURLOPT_URL, $url);
    if ($this->proxy != '') {
        curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
        curl_setopt($ch, CURLOPT_PROXYPORT, $this->port);
        curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->userpwd);
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSLVERSION, 3);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("
         POST /oauth2/token HTTP/1.1
         Host: api.twitter.com
         User-Agent: My Twitter App v1.0.23
         Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
         Content-Type: application/x-www-form-urlencoded;charset=UTF-8
         Content-Length: 29
         Accept-Encoding: gzip
         grant_type=client_credentials
    "));
    $response = curl_exec($ch);
    if (FALSE === $response) throw new Exception(curl_error($ch), curl_errno($ch));
        curl_close($ch);
        var_dump(json_decode($response));
} 
catch(Exception $e) {
    trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}

Which gives me

Fatal error: Curl failed with error #35: Unknown SSL protocol error in connection to api.twitter.com

file_get_contents:

$context = stream_context_create(array(
    "http" => array(
    "method"=>"CONNECT",
    "proxy" => $this->proxy.":".$this->port,
    "request_fulluri" => true,
    "header" => "
        POST /oauth2/token HTTP/1.1
        Host: api.twitter.com
        User-Agent: My Twitter App v1.0.23
        Proxy-Authorization: Basic ".base64_encode(urlencode($this->userpwd))."
        Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
        Content-Type: application/x-www-form-urlencoded;charset=UTF-8
        Content-Length: 29
        Accept-Encoding: gzip
        grant_type=client_credentials
        ",
    ),
));
$response = file_get_contents($url, False, $context);
var_dump(json_decode($response));

Which gives me

Warning: file_get_contents(https://api.twitter.com/oauth2/token) [function.file-get-contents]: failed to open stream: Cannot connect to HTTPS server through proxy

fsockopen:

$fp = fsockopen($this->proxy, $this->port);
fputs($fp, "
    POST /oauth2/token HTTP/1.1
    Host: api.twitter.com
    User-Agent: My Twitter App v1.0.23
    Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
    Content-Type: application/x-www-form-urlencoded;charset=UTF-8
    Content-Length: 29
    Accept-Encoding: gzip
    grant_type=client_credentials
");
$data="";
while (!feof($fp)) $data .= fgets($fp,1024);
fclose($fp);
var_dump($data);

Which gives me

HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Proxy-Connection: close
Connection: close
Content-Length: 727

I am sure that the 443 port is open and it's not a problem of the localhost (I got the same error trying on an online server).

I tried even using CONNECT method instead of POST. I tried tunneling the proxy, but I'm neither sure I made it nor that that's the problem.

I'm running out ideas..

Était-ce utile?

La solution 2

Found the problem. There's no need (maybe only in this case, i'm not sure) to base64 encode the credentials. They'll be encoded by the server.

I don't know the reason of that different error responses, but was in fact a problem of double encoding, because of which the server was not able to verify my credentials.

Autres conseils

Try to remove this:

curl_setopt($ch, CURLOPT_SSLVERSION, 3);

You only have one value in this array, it's wrong.

curl_setopt($ch, CURLOPT_HTTPHEADER, array("
         POST /oauth2/token HTTP/1.1
         Host: api.twitter.com
         User-Agent: My Twitter App v1.0.23
         Authorization: Basic ".base64_encode(urlencode($consumer_key).":".urlencode($consumer_secret))."
         Content-Type: application/x-www-form-urlencoded;charset=UTF-8
         Content-Length: 29
         Accept-Encoding: gzip
         grant_type=client_credentials
    "));

Change the above for this:

$consumer_key = base64_encode(urlencode($consumer_key);
$consumer_secret = urlencode($consumer_secret);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
         "Host: api.twitter.com",
         "User-Agent: My Twitter App v1.0.23",
         "Authorization: Basic $consumer_key:$consumer_secret",
         "Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
         "Accept-Encoding: gzip",
         "grant_type=client_credentials"
         ));

if you want to include the Content-Length: xx, you need to use strlen() to get string length of the post, ex;

$length = strlen($post_content);

Then add it to the CURLOPT_HTTPHEADER array:

"Content-Length: $length"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top