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 следующим образом:
Это, очевидно, приводит к странице 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-код и посмотрите, поможет ли это.