Question

I'm trying to set up Bitbucket OAuth for my site but for some reason Bitbucket is not properly redirecting back to my site. I've created an OAuth key and secret and I'm using the Guzzle OAuth plugin in my Silex application.

First I request a temporary token via the oauth/request_token endpoint. Using that token I redirect to oauth/authenticate endpoint:

$app->get(
    '/auth/bitbucket',
    function () use ($app) {
        $client = new Client('https://bitbucket.org/api/1.0');
        $oauth = new OauthPlugin(
            array(
                'consumer_key' => $app['bitbucket.key'],
                'consumer_secret' => $app['bitbucket.secret'],
                'signature_method' => 'HMAC-SHA1',
                'callback' => urlencode('http://mysite.local/auth/bitbucket/callback')
            )
        );
        $client->addSubscriber($oauth);

        $response = $client->post('oauth/request_token')->send();

        parse_str($response->getBody(), $result);

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

This will bring up the page on the Bitbucket site where the user can grant or deny access to their account. After I click "Grant access" Bitbucket should redirect back to the callback url that was specified earlier but instead it will append my callback url to the Bitbucket url like this:

https://bitbucket.org/api/1.0/oauth/http%3A%2F%2Fmysite.local%2Fauth%2Fbitbucket%2Fcallback?oauth_verifier=xxxxxxxxxx&oauth_token=xxxxxxxxxxxxxxxxxx

This obviously results in a Bitbucket 404 page. Does anyone have an idea why the redirect to my callback url is not working properly?

Was it helpful?

Solution

According to documentation, when requesting token from bitbucket's API, you MUST have those parameters when sending POST request to https://bitbucket.org/api/1.0/oauth/request_token:

  • oauth_consumer_key
  • oauth_nonce
  • oauth_signature
  • oauth_signature_method
  • oauth_timestamp
  • oauth_callback



Also, don't urlencode your callback URL. Replace this:

'callback' => urlencode('http://mysite.local/auth/bitbucket/callback')

With this:

'callback' => 'http://mysite.local/auth/bitbucket/callback'

When you are sending POST request, you do not need to encode any of parameters.




Indeed, as you mentioned in comment, documentation does show encoded parameters in example, as in:

https://bitbucket.org/api/1.0/oauth/request_token?oauth_version=1.0&oauth_nonce=7f2325b3c36bd49afa0a33044d7c6930&oauth_timestamp=1366243208&oauth_consumer_key=HUpRcDUduZrepL6sYJ&oauth_callback=http%3A%2F%2Flocal%3Fdump&oauth_signature_method=HMAC-SHA1&oauth_signature=qZyTwVA48RzmtCHvN9mYWmlmSVU%3D

Issue you have is not wrong documentation, but misunderstanding of POST method. Also check Wikipedia page. Unlike GET where parameters are passed in URL, POST request method stores it's data in body. That allows us to send any data type, arbitrarily long.

Data that is passed in body of request is automatically encoded as in this example (copied from Wikipedia page):

Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21

Looks similar to GET method when you encode data manually, right? However, if you urlencode data in POST request you actually end up with double encoded data, which is cause of problems in your case.


I really think that some basic knowledge of HTTP methods and Internet protocols is required before playing with any API.

Also, check some HTTP traffic monitor (debugger), like free Fiddler. It will allow you to see all HTTP data that is sent from your browser, essentially enabling you to learn by own examples.

OTHER TIPS

I'm not sure how your framework works, but the callback parameter may be url encoded by the framework before the request is made. Since you also url encode it, your url is url encoded twice. Bitbucket will decode it once, leaving it with a url encoded url, which won't have the scheme set (http in this case), and your browser won't know it is an absolute URL, and will thus navigate to somewhere inside Bitbucket (as you observe). Try removing the extra url encode and see if that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top