3
votes

I can't wrap my brain around why this isn't work... I really think it should be. Please help.

Here is the error I get:

signature_invalid base_string:GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dhttp%253A%252F%252Fnoveis.net%252Fauthsub%252Findex.php%26oauth_consumer_key%CONSUMER KEY HERE%26oauth_nonce%3D3bafa031c03f6d1590f2539091245270%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1282159845%26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fwww.googleapis.com%252Fauth%252Flatitude

Here is my code:

<?php

$consumer = ''; // Would be consumer key
$secret = ''; // Would be secret
$callback = ''; // Would be callback URL

$mt = microtime();
$rand = mt_rand();
$nonce = md5($mt . $rand);
$time = time();

$url = 'https://www.google.com/accounts/OAuthGetRequestToken';
$path = '/accounts/OAuthGetRequestToken';

$scope = 'https://www.googleapis.com/auth/latitude';

$post = array(
    'oauth_callback' => $callback,
    'oauth_consumer_key' => $consumer,
    'oauth_nonce' => $nonce,
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_timestamp' => $time,
    'oauth_version' => '1.0'
);

$post_string = '';
foreach ($post as $key => $value) {
    $post_string .= $key . '=' . urlencode($value) . '&';
}
$post_string = rtrim($post_string, '&');

$key_parts = array($consumer, $secret);

$key_parts = array_map('urlencode', $key_parts);
$key = implode('&', $key_parts);

$base_string = 'GET&' . urlencode($scope) . '&' . $post_string;
$signature = base64_encode(hash_hmac('sha1', $base_string, $key, true));
$post['oauth_signature'] = $signature;
$header_string = '';
foreach ($post as $key => $value) {
    $header_string .= $key . '="' . urlencode($value) . '", ';
}
$header_string = trim($header_string);
$header_string = rtrim($header_string, ',');

$header[] = 'GET ' . $path . '?scope=' . urlencode($scope) . ' HTTP/1.1';
$header[] = 'Host: www.google.com';
$header[] = 'Accept: */*';
//$header[] = 'Content-Type: application/x-www-form-urlencoded';
$header[] = 'Authorization: OAuth ' . $header_string;
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_URL, $url . '?scope=' . $scope);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
?>
1

1 Answers

6
votes

Well, I solved my own problem. I went through this line by line, bit by bit and I got it. The problems were I was doing my consumer & secret to sign, when it should have been just my secret, and then it was the differences that should be in the Authorization header compared to what needs to be in the signature.

Here is my code if it'll help anyone else:

$consumer = '';
$secret = '';
$callback = '';
$sign_method = 'HMAC-SHA1';
$version = '1.0';
$scope = 'https://www.googleapis.com/auth/latitude';

function urlencodeRFC3986($string)
{
   return str_replace('%7E', '~', rawurlencode($string));
}


$mt = microtime();
$rand = mt_rand();
$nonce = md5($mt.$rand);
$time = time();

$url = 'https://www.google.com/accounts/OAuthGetRequestToken';
$path = '/accounts/OAuthGetRequestToken';

$post = array(
    'oauth_callback' => urlencodeRFC3986($callback),
    'oauth_consumer_key' => $consumer,
    'oauth_nonce' => $nonce,
    'oauth_signature_method' => $sign_method,
    'oauth_timestamp' => $time,
    'oauth_version' => $version,
    'scope' => urlencodeRFC3986($scope)
);

$post_string = '';
foreach($post as $key => $value)
{
    $post_string .= $key.'='.($value).'&';
}
$post_string = rtrim($post_string, '&');

$key_parts = array($secret);

$key_parts = urlencodeRFC3986($secret);
//$key = implode('&', $key_parts);
$key = $key_parts.'&';
$base_string = 'GET&'.urlencodeRFC3986($url).'&'.urlencodeRFC3986($post_string);
$signature = base64_encode(hash_hmac('sha1', $base_string, $key, true));


$post = array(
    'oauth_version' => $version,
    'oauth_nonce' => $nonce,
    'oauth_timestamp' => $time,
    'oauth_consumer_key' => $consumer,
    'oauth_callback' => $callback,
    'oauth_signature_method' => $sign_method,
    'oauth_signature' => $signature
);        

$header_string = '';
foreach($post as $key => $value)
{
    $header_string .= $key.'="'.urlencodeRFC3986($value).'", ';
}

$header_string = trim($header_string);
$header_string = rtrim($header_string, ',');

$header[] = 'GET '.$path.'?scope='.urlencodeRFC3986($scope).' HTTP/1.1';
$header[] = 'Host: www.google.com';
$header[] = 'Accept: */*';
//$header[] = 'Content-Type: application/x-www-form-urlencoded';
$header[] = 'Authorization: OAuth '.$header_string;


$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_URL, $url.'?scope='.$scope);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
die();
?>