Статьи

Понимание OAuth — Чирикать с нуля, часть 1

Распространенная жалоба на OAuth заключается в том, что ее очень трудно понять, но, возможно, некоторая путаница связана с ожиданием того, что абстракция, предоставляемая сторонней библиотекой, избавит от необходимости понимать шаги транзакции OAuth — она ​​делает не. Эта статья, состоящая из двух частей, демонстрирует, как работает OAuth v1 , объясняя процесс подключения приложения PHP к API Twitter с использованием всего нескольких встроенных функций для отправки сообщения в поток Twitter пользователя.

Пример кода, приведенный в этой статье, предназначен только для образовательных целей. В нем не хватает практического использования и обработки ошибок. Любая реальная разработка должна использовать преимущества существующей библиотеки OAuth, но после прочтения этой статьи вы лучше поймете, как работает OAuth, и будете лучше подготовлены к устранению любых проблем, которые могут возникнуть.

Получение потребительских полномочий

Публикация в Twitter от имени пользователя без запроса сочетания имени пользователя и пароля каждый раз требует своего рода «ключ камердинера»… этот ключ — OAuth. С точки зрения OAuth, ваше клиентское приложение называется потребителем , пользователь называется владельцем ресурса , а Twitter является сервером или поставщиком услуг .

Прежде чем Twitter примет сообщение из вашего приложения, вам необходимо получить свои собственные учетные данные клиента: Ключ потребителя и Секрет потребителя . Twitter, как и большинство служб, предоставляющих общедоступный API, предоставит вам ключ и секрет после заполнения регистрационной формы (доступно по адресу dev.twitter.com/apps ). С помощью Twitter вам необходимо предоставить некоторую информацию, которая будет идентифицировать ваше приложение для пользователя в процессе авторизации, в частности его имя, описание и URL-адрес веб-сайта. Вам также необходимо ввести URL обратного вызова, который я объясню позже.

После того как вы отправите форму «Создать заявку», вы попадете на страницу «Подробности» для вашего нового заявления. Прокрутите вниз, чтобы найти свой Ключ и Секрет потребителя. Они понадобятся вам вместе с несколькими указанными URL-адресами конечных точек. Обратите внимание, что приложению по умолчанию предоставляется доступ только для чтения; поскольку он будет публиковать твиты, вам нужно нажать на вкладку «Настройки» и изменить доступ на «Чтение и запись».

Авторизация приложения

Consumer Key и Consumer Secret позволяют вашему приложению взаимодействовать с API Twitter, но только они не позволяют публиковать твиты от имени другого пользователя. Вам нужны учетные данные для доступа: токен доступа и секрет доступа . Чтобы получить их через запрос к поставщику услуг (Twitter) в коротком разговоре с использованием учетных данных потребителя с участием Twitter и конечного пользователя. Получение учетных данных может быть довольно болезненным, но, к счастью, вам нужно сделать это только один раз для каждого пользователя. Вы можете сохранять учетные данные на неопределенное время для последующего использования и не требовать от пользователя повторной авторизации вашего приложения. Диалог, запрашивающий учетные данные доступа, требует своего собственного набора учетных данных: токена запроса и секрета запроса .

Шаг авторизации 1: запрос учетных данных

Процесс авторизации обычно начинается с направления пользователя на страницу авторизации Twitter. Это страница, которую вы создаете, которая инициирует запрос токена запроса из Twitter и начинает процесс авторизации OAuth. Он должен сгенерировать URL-адрес, используемый для получения учетных данных запроса, и как только у вас есть эти учетные данные, вы можете перенаправить пользователя в Twitter, чтобы предоставить приложению разрешение на публикацию.

Для запроса учетных данных запроса требуется подписанный запрос, что означает, что вам необходимо отправить подпись OAuth вместе с другими важными параметрами в запросе. Подпись является хешированным списком параметров запроса в кодировке base64. В случае с Twitter алгоритм хеширования — HMAC-SHA1. Процесс подписи не позволяет кому-либо выдавать себя за ваше приложение с вашими учетными данными, даже если Ключ потребителя передается в виде простого текста. Подпись может быть воспроизведена только вами (Потребителем) и сервером (Twitter), поскольку вы являетесь единственными объектами, которые должны знать Секретный код потребителя, который хэширует подпись.

Давайте построим строку, на которой основана подпись:

<?php $requestTokenUrl = "http://api.twitter.com/oauth/request_token"; $authorizeUrl = "http://api.twitter.com/oauth/authorize"; $oauthTimestamp = time(); $nonce = md5(mt_rand()); $oauthSignatureMethod = "HMAC-SHA1"; $oauthVersion = "1.0"; $sigBase = "GET&" . rawurlencode($requestTokenUrl) . "&" . rawurlencode("oauth_consumer_key=" . rawurlencode($consumerKey) . "&oauth_nonce=" . rawurlencode($nonce) . "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod) . "&oauth_timestamp=" . $oauthTimestamp . "&oauth_version=" . $oauthVersion); 

Некоторые из приведенных выше переменных могут быть довольно очевидными — $requestTokenUrl был получен из Twitter, когда вам были предоставлены учетные данные потребителя, а $oauthTimestamp — текущее время эпохи UNIX. Менее очевидный элемент — это $nonce , который является не более чем случайной строкой, используемой только один раз (для каждой транзакции используется одноразовый номер разницы). Обычно случайное число с хэшированием MD5 отлично работает как одноразовый номер. Существует также $oauthSignatureMethod который всегда является HMAC-SHA1 для Twitter, и $oauthVersion который в настоящее время v1.0 для Twitter.

Далее строка для подписи $sigBase как $sigBase . OAuth говорит, что основой подписи должен быть метод HTTP (в данном случае GET ), за которым следует «&», затем URL запроса в кодировке URL ( $requestTokenUrl ), затем другой «&» и, наконец, кодировка URL и алфавитный список пар ключ / значение параметра (значения которых также должны быть закодированы), разделенных символом «&». Обратите внимание, что когда OAuth хочет что-то в кодировке URL, это означает RFC-3986 . rawurlencode() PHP rawurlencode() работает, потому что она кодирует пробелы как «% 20» вместо «+», как это делает urlencode() .

Вам также нужен подписывающий ключ. Ключом всегда является Consumer Secret, за которым следуют «&» и либо 1) OAuth Token Secret (который является частью Token Credentials, которых у вас еще нет), либо 2) ничего. Затем вы можете сгенерировать окончательную подпись, используя встроенную в hash_hmac() функцию hash_hmac() .

 <?php $sigKey = $consumerSecret . "&"; $oauthSig = base64_encode(hash_hmac("sha1", $sigBase, $sigKey, true)); 

Вы складываете все части вместе, чтобы создать URL-адрес для запроса учетных данных запроса:

 <?php $requestUrl = $requestTokenUrl . "?" . "oauth_consumer_key=" . rawurlencode($consumerKey) . "&oauth_nonce=" . rawurlencode($nonce) . "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod) . "&oauth_timestamp=" . rawurlencode($oauthTimestamp) . "&oauth_version=" . rawurlencode($oauthVersion) . "&oauth_signature=" . rawurlencode($oauthSig); $response = file_get_contents($requestUrl); 

Вы захотите гораздо больше обработки ошибок для чего-либо, кроме этой простой демонстрации, но сейчас я предполагаю, что ничего не пойдет не так, и вы сможете получить временные учетные данные запроса в $response .

Ответ от Twitter выглядит так:

  oauth_token = mjeaYNdNYrvLBag6xJNWkxCbgL5DV6yPZl6j4palETU & oauth_token_secret = W45dnBz917gsdMqDu4bWNmShQq5A8pRwoLnJVm6kvzs & oauth_callback_confirmed = верно 

Значения oauth_token и oauth_token_secret извлекаются из ответа и используются для создания следующей ссылки, на которую пользователь переходит на второй этап процесса авторизации. Рекомендуется хранить учетные данные запроса в сеансе пользователя, чтобы они были доступны, когда пользователь вернется со страницы авторизации Twitter. URL-адрес авторизации указывается на странице сведений после регистрации приложения в Twitter.

 <?php parse_str($response, $values); $_SESSION["requestToken"] = $values["oauth_token"]; $_SESSION["requestTokenSecret"] = $values["oauth_token_secret"]; $redirectUrl = $authorizeUrl . "?oauth_token=" . $_SESSION["requestToken"]; header("Location: " . $redirectUrl); 

Теперь, когда приложение может отправлять пользователей в Twitter для авторизации, самое время добавить URL обратного вызова, чтобы Twitter мог отправить их обратно в приложение! URL обратного вызова — это просто адрес, на который Twitter направит пользователя после того, как он разрешит вашему приложению отправлять твиты от его имени, и указан на вкладке «Настройки» на странице «Подробно».

Когда Twitter перенаправляет пользователя на URL-адрес обратного вызова, он добавляет два дополнительных параметра: ваш oauth_token из исходного запроса, который можно использовать для проверки, и oauth_verifier который используется при получении учетных данных авторизации.

Из трех наборов учетных данных, необходимых для публикации твитов, теперь у вас есть два — учетные данные потребителя и учетные данные запроса. Далее: Доступ к учетным данным!

Шаг авторизации 2: Доступ к учетным данным

Чтобы получить учетные данные для доступа, вам нужны oauth_token , oauth_token_secret и недавно полученный oauth_verifier . Для этого шага требуется еще один подписанный запрос, на этот раз для URL-адреса токена доступа, отображаемого на странице сведений.

 <?php $oauthVersion = "1.0"; $oauthSignatureMethod = "HMAC-SHA1"; $accessTokenUrl = "http://api.twitter.com/oauth/access_token"; $nonce = md5(mt_rand()); $oauthTimestamp = time(); $oauthVerifier = $_GET["oauth_verifier"]; 

$accessTokenUrl — следующая конечная точка, полученная на странице сведений. $oauthTimestamp новые $oauthTimestamp и $nonce , а $oauthVerifier отправляется обратно со страницы авторизации Twitter. Не указаны, но в $_SESSION находятся учетные данные запроса из предыдущего шага, которые также необходимы.

Этот шаг процесса авторизации требует еще одного подписанного запроса. Как только подпись построена, она используется с запросом на учетные данные для доступа.

 <?php $sigBase = "GET&" . rawurlencode($accessTokenUrl) . "&" . rawurlencode("oauth_consumer_key=" . rawurlencode($consumerKey) . "&oauth_nonce=" . rawurlencode($nonce) . "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod) . "&oauth_timestamp=" . rawurlencode($oauthTimestamp) . "&oauth_token=" . rawurlencode($_SESSION["requestToken"]) . "&oauth_verifier=" . rawurlencode($oauthVerifier) . "&oauth_version=" . rawurlencode($oauthVersion)); $sigKey = $consumerSecret . "&"; $oauthSig = base64_encode(hash_hmac("sha1", $sigBase, $sigKey, true)); $requestUrl = $accessTokenUrl . "?" . "oauth_consumer_key=" . rawurlencode($consumerKey) . "&oauth_nonce=" . rawurlencode($nonce) . "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod) . "&oauth_timestamp=" . rawurlencode($oauthTimestamp) . "&oauth_token=" . rawurlencode($_SESSION["requestToken"]) . "&oauth_verifier=" . rawurlencode($oauthVerifier) . "&oauth_version=". rawurlencode($oauthVersion) . "&oauth_signature=" . rawurlencode($oauthSig); $response = file_get_contents($requestUrl); 

На этот раз $response имеет очень полезные user_id , user_id и долгожданные учетные данные Access!

Резюме

На этом мы завершаем авторизационную часть этой статьи. Итак, вы узнали, как создать новое приложение Twitter и использовать предоставленные учетные данные потребителя, чтобы пройти «танец» OAuth для получения учетных данных доступа. Во второй и последней части этой серии я расскажу об использовании учетных данных для доступа, чтобы опубликовать твит в ленте пользователя в Твиттере.

Изображение через Quin / Shutterstock