OAuth Bitbucket API не перенаправляет должным образом

Я пытаюсь настроить Bitbucket OAuth для своего сайта, но по какой-то причине Bitbucket неправильно перенаправляет обратно на мой сайт. Я создал ключ и секрет OAuth и использую плагин Guzzle OAuth в своем приложении Silex.

Сначала я запрашиваю временный токен через конечную точку oauth/request_token. Используя этот токен, я перенаправляю на конечную точку oauth/authenticate:

$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']));
    }
);

Это откроет страницу на сайте Bitbucket, где пользователь может предоставить или запретить доступ к своей учетной записи. После того, как я нажму "Предоставить доступ", Bitbucket должен перенаправить обратно на URL обратного вызова, который был указан ранее, но вместо этого он добавит мой URL обратного вызова к URL Bitbucket следующим образом:

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

Это, очевидно, приводит к странице Bitbucket 404. Кто-нибудь есть идея, почему перенаправление на мой URL обратного вызова не работает должным образом?

2 ответа

Решение

Согласно документации, при запросе токена из API-интерфейса bitbucket вы ДОЛЖНЫ иметь эти параметры при отправке запроса POST по https://bitbucket.org/api/1.0/oauth/request_token:

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



Кроме того, не кодируйте URL вашего обратного вызова. Заменить это:

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

С этим:

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

Когда вы отправляете запрос POST, вам не нужно кодировать ни один из параметров.




Действительно, как вы упомянули в комментарии, документация показывает закодированные параметры в примере, например:

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

Проблема не в документации, а в неправильном понимании метода POST. Также проверьте страницу Википедии. В отличие от GET, где параметры передаются в URL, метод запроса POST сохраняет данные в теле. Это позволяет нам отправлять данные любого типа, произвольно долго.

Данные, которые передаются в теле запроса, автоматически кодируются, как в этом примере (скопировано со страницы Википедии):

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

Похоже на метод GET, когда вы кодируете данные вручную, верно? Однако, если вы urlencode данных в запросе POST, вы на самом деле в конечном итоге с данными с двойным кодированием, что является причиной проблем в вашем случае.


Я действительно думаю, что некоторые базовые знания о методах HTTP и интернет-протоколах необходимы, прежде чем играть с любым API.

Также проверьте некоторый монитор трафика HTTP (отладчик), например бесплатный Fiddler. Это позволит вам увидеть все HTTP-данные, отправленные из вашего браузера, что, в сущности, позволит вам учиться на собственных примерах.

Я не уверен, как работает ваш фреймворк, но параметр обратного вызова может быть закодирован URL-адресом фреймворком перед выполнением запроса. Поскольку вы также URL-адрес кодировать его, ваш URL-адрес кодируется дважды. Bitbucket декодирует его один раз, оставляя его с URL-адресом в кодировке URL, для которого не будет установлена ​​схема (в данном случае http), и ваш браузер не будет знать, что это абсолютный URL-адрес, и, таким образом, перейдет куда-то внутрь Bitbucket (как вы наблюдаете). Попробуйте удалить дополнительный URL-код и посмотрите, поможет ли это.

Другие вопросы по тегам