Question

I have been trying to implement a simple authentication flow using OAuthv1.a and bit bucket. My issue occurs when I make a request for access tokens using the previously supplied verifier and oauth_token. I am always given a 400 error with no real indication as to why.

Client error response
[status code] 400
[reason phrase] BAD REQUEST
[url] https://bitbucket.org/api/1.0/oauth/access_token?oauth_consumer_key=<snip>&oauth_nonce=fba24cfb3147ca7d32b3924fad43fd509bbb9bc1&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1381034857&oauth_token=fFz369NUmCHNyn7PGj&oauth_verifier=6724267371&oauth_version=1.0&oauth_signature=1H7%2Bvx0fVh2Sj%2FcDAE2QzkTx8us%3D

I am using the OauthPlugin class within guzzle to build signed parameters and submitting post requests as described in the documentation. Has anyone had an issue like this with any other OAuthv1 provider or Bit Bucket specifically?

$client = new Client('https://bitbucket.org/api/1.0/');

    $oauth  = new OauthPlugin( array(
        'request_method' => OauthPlugin::REQUEST_METHOD_QUERY,
        'consumer_key'  => Config::get('oauthv1.key'),
        'token' => Input::get('oauth_token'),
        'verifier' => Input::get('oauth_verifier')
        )
    );

    $client->addSubscriber($oauth);
    $client->post('oauth/access_token')->send();
Was it helpful?

Solution

Even though the Bitbucket API documentation doesn't mention it, the call to the oauth/access_token endpoint also requires the consumer_secret and oauth_token_secret. The consumer secret is generated by Bitbucket when you create your app and should be stored in your config. You can get the oauth_token_secret from the response of the call to oauth/request_token. Just save it in the session so you can use it when getting the access token.

Request a request token:

$client = new Client('https://bitbucket.org/api/1.0');
$oauth = new OauthPlugin(array(
    'consumer_key'    => $app['bitbucket.key'],
    'consumer_secret' => $app['bitbucket.secret'],
    'callback'        => 'http://mysite.local/callback',        
));
$client->addSubscriber($oauth);
$response = $client->post('oauth/request_token')->send();

// Parse the response
parse_str($response->getBody(), $result);

// Save the token secret in the session
$app['session']->set('oauth_token_secret', $result['oauth_token_secret']);

// Redirect to Bitbucket to authorize the application
return $app->redirect(sprintf('https://bitbucket.org/api/1.0/oauth/authenticate?oauth_token=%s', $result['oauth_token']));

Request an access Token:

$token       = $app['request']->get('oauth_token');
$verifier    = $app['request']->get('oauth_verifier');
$tokenSecret = $app['session']->get('oauth_token_secret');

$client = new Client('https://bitbucket.org/api/1.0');
$oauth = new OauthPlugin(array(
    'consumer_key'    => $app['bitbucket.key'],
    'consumer_secret' => $app['bitbucket.secret'],
    'token'           => $token,
    'token_secret'    => $tokenSecret,
    'verifier'        => $verifier,
));
$client->addSubscriber($oauth);
$client->post('oauth/access_token')->send();

// Parse the response
$response = parse_str($response->getBody(), $result);

// Get the access token
$accessToken = $result['oauth_token'];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top