Как использовать OAuth-аутентификацию с REST API с помощью команд CURL?

18

Я пытаюсь использовать WordPress Rest Api с аутентификацией, чтобы получить больше данных от API. Я установил плагин Oauth, плагин rest-api и получил учетные данные API от WP-CLI.

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

// set our end point
$domain = "http://localhost/wp-api";
$endpoint = $domain."/wp-json/wp/v2/posts/";


$curl = curl_init($endpoint);

curl_setopt_array($curl, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_URL            => $endpoint,
]);
$response = curl_exec($curl);
$decoderesponse = json_decode($response, true);

?>

<pre>
  <?php print_r($decoderesponse); ?>
</pre>

Но я не могу понять, как пройти аутентификацию с помощью учетных данных. Вот моя попытка. Я не уверен, что «ключ» и «секрет» верны.

// Oauth credentials from wp-cli
$ID = "4";
$Key = "l8XZD9lX89kb";
$Secret = "UUbcc8vjUkGjuDyvK1gRTts9sZp2N8k9tbIQaGjZ6SNOyR4d";

// set our end point
$domain = "http://localhost/wp-api";
$endpoint = $domain."/wp-json/wp/v2/posts/1/revisions";

$headers[] = "key=$Key";
$headers[] = "secret=$Secret";

$curl = curl_init($endpoint);

curl_setopt_array($curl, [
  CURLOPT_HTTPHEADER     => $headers,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_URL            => $endpoint,
]);
$response = curl_exec($curl);
$decoderesponse = json_decode($response, true);

?>

<pre>
  <?php print_r($decoderesponse); ?>
</pre>

Выход

Array
(
    [code] => rest_cannot_read
    [message] => Sorry, you cannot view revisions of this post.
    [data] => Array
        (
            [status] => 401
        )
)

Как я могу заставить это работать? Спасибо.

JediTricks007
источник
2
Все не так просто. Я пытался написать ответ, но это довольно долго. Вы могли бы начать с чтения документов, в частности, потока авторизации . Этот пост также имеет отличный учебник .
cybmeta

Ответы:

10

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

Поскольку для этого используется OAuth версии 1, для получения токена доступа необходимо выполнить следующее:

  1. Сначала настройте приложение, позвоните на сайт, чтобы получить токен запроса (временные учетные данные), используя идентификатор клиента и секрет для приложения.
  2. Во-вторых, сделайте звонок на сайт, чтобы с первого шага авторизовать приложение с помощью токена запроса ( с обращением к пользователю, см. Ниже).
  3. В-третьих, после того, как авторизация была завершена, вы звоните на сайт, чтобы получить токен доступа (теперь, когда приложение авторизовано)

Я рекомендую использовать Почтальон для первых нескольких шагов, потому что они должны быть выполнены только один раз. Почтальон также будет обрабатывать генерацию timestamp, nonceи oauth signature, если вы не используете библиотеку OAuth, то вам обязательно следует использовать Почтальон. Получив токен доступа, вы можете совершать звонки через CURL без каких-либо библиотек.

https://www.getpostman.com/

Первый шаг (настройка приложения)

Установите плагин WP OAuth 1, активируйте его, затем перейдите в пункт меню « Пользователи»> «Приложения» . Добавить новую заявку, заполнить имя и описание. Для обратного вызова либо URL-адрес, на который перенаправляется пользователь (после авторизации), либо oopвнеполосный поток, который перенаправляет на внутреннюю страницу, на которой отображается токен верификатора (вместо перенаправления).

https://github.com/WP-API/OAuth1/blob/master/docs/basics/Registering.md

Для того, чтобы перейти ко второму шагу должен быть сделан на ваш сайт, используя вызов ID клиента и секрет клиента из созданного приложения, чтобы получить временные данные (идентификатор запроса).

Откройте Почтальон, создайте новый вызов http://website.com/oauth1/request, нажмите на вкладку Авторизация, выберите OAuth 1.0 из раскрывающегося списка, введите ключ клиента, Client Secret, установите метод подписи на HMAC-SHA1, разрешите добавлять параметры в заголовок, кодируйте подпись oauth , затем нажмите « Обновить запрос».

Почтальон OAuth1 Запрос

Почтальон автоматически сгенерирует подпись, одноразовый номер и временную метку для вас, и добавит их в заголовок (вы можете просмотреть на вкладке Заголовки).

Нажмите «Отправить», и вы должны получить ответ, который включает oauth_tokenи oauth_token_secret: Почтальон OAuth1 Запрос ответа

Эти значения будут использованы на следующем шаге для авторизации приложения под вашей учетной записью WordPress.

Второй шаг (авторизовать приложение)

Шаг авторизации необходимо выполнить только один раз, этот шаг ориентирован на пользователя и знаком всем. Этот шаг необходим, потому что вы используете OAuth1, и приложение должно быть связано с учетной записью пользователя WordPress. Подумайте, когда сайт позволяет вам войти через Facebook ... они направляют вас в Facebook, где вы входите, и нажимаете «Авторизовать» ... это нужно сделать, просто через ваш сайт WordPress.

Я рекомендую использовать ваш веб-браузер для этого шага, так как вы можете легко установить переменные в URL, и это обеспечивает страницу «Авторизация» для авторизации приложения.

Откройте веб-браузер и введите URL-адрес своего сайта, например: http://website.com/oauth1/authorize

Теперь добавьте к этому URL oauth_consumer_key(идентификатор клиента) oauth_tokenи oauth_token_secret(с предыдущего шага). В моем примере это полный URL:

http://website.com/oauth1/authorize?oauth_consumer_key=TUPFNj1ZTd8u&oauth_token=J98cN81p01aqSdFd9rjkHZWI&oauth_token_secret=RkrMhw8YzXQljyh99BrNHmP7phryUvZgVObpmJtos3QExG1O

OAuth1 Авторизовать приложение

После того, как вы нажмете «Авторизовать», вы получите другой экран с токеном подтверждения. В моем примере это возвращенный токен подтвержденияE0JnxjjYxc32fMr2AF0uWsZm

Третий шаг (получить токен доступа)

Теперь, когда мы авторизовали приложение, нам нужно сделать один последний вызов, чтобы получить токен авторизации, который будет использоваться для выполнения всех ваших вызовов API. Так же, как на первом шаге я собираюсь использовать Почтальон (потому что подпись должна быть HMAC-SHA1), и это облегчает выполнение этих шагов в 100 раз.

Снова откройте Почтальон и измените URL на http://website.com/oauth1/access

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

Почтальон OAuth1 шаг доступа

Убедитесь в том , чтобы нажать Update Request, а затем нажмите кнопку Отправить, и вы должны получить ответ обратно с oauth_tokenи oauth_token_secret... это то , что вам нужно сделать API вызовы с! Откажитесь от оригинальных с шага 1, сохраните их в своем коде или в другом безопасном месте.

Почтальон OAuth1 Access Response

Затем вы можете сделать API-вызов на ваш сайт, установив заголовки с возвращенным токеном и секретом токена.

Вы можете передать это несколькими способами, через заголовок авторизации, в параметрах GET или POST (если он закодирован как application / x-www-form-urlencoded). Имейте в виду, что вы ДОЛЖНЫ передать подпись, отметку времени и одноразовый номер. Я не осознавал, сколько времени займет этот ответ, поэтому я обновлю это завтра с примером того, как сделать это с вашим кодом.

Я настоятельно рекомендую установить журнал Rest API, чтобы вы могли просматривать журнал вызовов API и видеть, что было отправлено, возвращено и т. Д. Это очень поможет при отладке.

https://github.com/petenelson/wp-rest-api-log

sMyles
источник
Я знаю, что есть много учебных пособий по Postman или подобным инструментам, но я не могу найти никаких учебных пособий, которые бы выполняли весь процесс с использованием функций CURL, я имею в виду чистый PHP-код. Это то, что я хочу.
MinhTri
@ Dan9 TBH, это на самом деле невозможно ... по крайней мере, не с OAuth1, в основном потому, что вам нужно авторизовать приложение под учетной записью пользователя. Все остальные шаги легко выполнить с помощью CURL, проблема заключается в использовании CURL для входа в систему в качестве пользователя WordPress (что означает, что вам нужно хранить учетные данные в вашем PHP-файле, что НЕ является хорошей идеей), И для авторизации приложения, которое вы может изменить кодовую базу OAuth1, но, если честно, если вы хотите использовать CURL, чтобы делать ВСЕ ... вы думаете об этом неправильно и должны найти другое решение или метод.
sMyles
@ Dan9 с тем, что вы пытаетесь сделать, вы должны использовать сервер OAuth2 вместо OAuth1, главным образом потому, что OAuth2 имеет новые функции, включая тип предоставления клиентских учетных данных, что позволяет избежать необходимости выполнять все эти шаги bshaffer.github.io / oauth2-server-php-docs / grant-types /…
sMyles
@ Dan9, если вы на 100% настроены на получение помощи при выполнении этого через OAuth1, используя CURL, я думаю, что это возможно с помощью нескольких хаков кода, но, как я уже говорил, это означает, что вы должны сохранить имя пользователя и пароль пользователя. в файл PHP. Если у вас все в порядке, дайте мне знать, и я напишу учебник, чтобы сделать это с помощью CURL, не хочу тратить время на написание учебника, если вы собираетесь использовать OAuth2 или вам это больше не нужно
sMyles
@ Dan9 хорошо ... вот и все ... если вы собираетесь использовать OAuth1, вам нужно связать учетную запись пользователя WordPress. По сути, токен доступа следует рассматривать как ключ API ... «Ключ API» должен быть связан с учетной записью пользователя ... теперь независимо от того, используете ли вы какую-либо стандартную учетную запись, которую вы настраиваете, решать вам ... но независимо от того, использует ли OAuth1 его ДОЛЖЕН быть связан с учетной записью пользователя, отсюда и длительный процесс получения токена доступа.
sMyles
2

Добавление этого в качестве другого ответа, чтобы помочь вам выяснить, как это сделать. В основном, как упоминалось в моих комментариях, если вы собираетесь использовать OAuth1, вы ДОЛЖНЫ связать его с учетной записью пользователя, никак не обойтись.

Сначала вам нужно использовать CURL для входа на сайт с паролем имени пользователя для WordPress, сохраните cookie-файл, чтобы вы могли использовать его в своем вызове CURL для OAuth (не забудьте обновить свой вызов CURL, чтобы включить cookie):

/programming/724107/wordpress-autologin-using-curl-or-fsockopen-in-php

Затем выполните вызов OAuth с использованием CURL с идентификатором клиента и секретом клиента, чтобы получить временный токен oauth и секрет (запрос токена)

Чтобы сделать этот вызов (и вызов для получения токена доступа), вам необходимо правильно настроить вызов CURL. Смотрите конец этого ответа для кода и ссылок.

После того, как вы получите временный токен oauth и секрет (Request Token), сделайте вызов CURL POST по этому URL вашего сайта:

http://website.com/oauth1/authorize

Затем вам нужно будет извлечь все значения из возвращенного HTML-кода для страницы авторизации, а затем отправить свой собственный POST по URL-адресу действия формы.

/programming/35363815/how-to-get-a-value-input-from-html-returned-of-curl

В частности, они должны быть включены в ваши данные POST, чтобы завершить «авторизацию» POST для http://domain.com/wp-login.php?action=oauth1_authorize

  • _wpnonce - Это одноразовое значение для формы, которая должна быть отправлена, она ДОЛЖНА быть извлечена из HTML-ввода и отправлена ​​с вашим POST

    consumer - Это скрытый ввод в HTML (это ссылка на идентификатор сообщения, поэтому вы должны извлечь его из ввода HTML

    oauth_token - Это скрытый ввод в HTML (но он также должен быть у вас)

    wp-submit - Это должно быть установлено в значение authorize

Вот пример HTML-кода, сгенерированного для страницы аутентификации:

<form name="oauth1_authorize_form" id="oauth1_authorize_form" action="http://website.com/wp-login.php?action=oauth1_authorize" method="post">

    <h2 class="login-title">Connect My Auth</h2>

    <div class="login-info">
        <p>Howdy <strong>admin</strong>,<br/> "My OAuth Demo" would like to connect to Example Site.</p>

    </div>

    <input type="hidden" name="consumer" value="5428" /><input type="hidden" name="oauth_token" value="i1scugFXyPENniCP4kABKtGb" /><input type="hidden" id="_wpnonce" name="_wpnonce" value="ca9b267b4f" /><input type="hidden" name="_wp_http_referer" value="/wp-login.php?action=oauth1_authorize&amp;oauth_consumer_key=TUPFNj1ZTd8u&amp;oauth_token=i1scugFXyPENniCP4kABKtGb&amp;oauth_token_secret=gzqW47pHG0tilFm9WT7lUgLoqN2YqS6tFFjUEiQoMgcmG2ic" />   <p class="submit">
        <button type="submit" name="wp-submit" value="authorize" class="button button-primary button-large">Authorize</button>
        <button type="submit" name="wp-submit" value="cancel" class="button button-large">Cancel</button>
    </p>

</form>

После того, как вы выполните POST со всеми этими значениями / данными, это HTML, который будет возвращен с кодом авторизации (поэтому вам нужно извлечь значение изнутри <code>блока:

<div id="login">
    <h1><a href="https://wordpress.org/" title="Powered by WordPress" tabindex="-1">Example Site</a></h1>
    <p>Your verification token is <code>yGOYFpyawe8iZmmcizqVIw3f</code></p> <p id="backtoblog"><a href="http://website.com/">&larr; Back to Example Site</a></p>
</div>

Получив токен подтверждения, вы можете позвонить, /oauth1/accessиспользуя токен подтверждения, токен oauth и токен oauth. Токен подтверждения должен быть помещен в данные POST какoauth_verifier

Это вернет ваш новый и постоянный токен доступа, и VOILA!

Пример кода CURL

Ниже приведен пример кода для вызова CURL, наиболее важной частью которого является то, как oauth_signatureгенерируется:

https://oauth1.wp-api.org/docs/basics/Signing.html

function buildBaseString($baseURI, $method, $params){
    $r = array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value);
    }

    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth){
    $r = 'Authorization: OAuth ';
    $values = array();
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\"";

    $r .= implode(', ', $values);
    return $r;
}

// Add request, authorize, etc to end of URL based on what call you're making
$url = "http://domain.com/oauth/";

$consumer_key = "CLIENT ID HERE";
$consumer_secret = "CLIENT SECRET HERE";

$oauth = array( 'oauth_consumer_key' => $consumer_key,
                'oauth_nonce' => time(),
                'oauth_signature_method' => 'HMAC-SHA1',
                'oauth_callback' => 'oob',
                'oauth_timestamp' => time(),
                'oauth_version' => '1.0');

$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;


$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array( CURLOPT_HTTPHEADER => $header,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$return_data = json_decode($json);

print_r($return_data);

На этом сайте подробно рассказывается, как кодировать подпись OAuth и как отправлять сообщения с использованием CURL (я рекомендую прочитать всю страницу): https://hannah.wf/twitter-oauth-simple-curl-requests-for-your-own- данные/

Дополнительный ресурс по созданию подписи OAuth1: /programming/24613277/oauth-signature-generation-using-hmac-sha1

Другие ресурсы: http://collaboradev.com/2011/04/01/twitter-oauth-php-tutorial/

sMyles
источник
Как я могу получить идентификатор клиента и секрет клиента и связать его с действительным пользователем? В настоящее время только администраторы могут создавать новое приложение, и это происходит только через панель администратора. Кстати, я пытался генерировать, oauth_signatureкак вы сказали, но, так или иначе, ответ всегда json_oauth1_signature_mismatch.
MinhTri
@ Dan9 да, это правильно, администраторы должны создавать приложение, в противном случае это было бы огромной проблемой безопасности, позволяющей создавать приложения анонимным пользователям. Вот некоторые сайты, касающиеся подписи wordpress.stackexchange.com/questions/185511/… github.com/WP-API/OAuth1/issues/34 github.com/WP-API/OAuth1/issues/27
sMyles
0

Обновление: из того, что я прочитал, вам нужно сделать несколько скручиваний, чтобы получить access_token, который вы затем используете для выполнения запроса

  • Получение временных учетных данных: клиент получает набор временных учетных данных с сервера.
  • Авторизация. Пользователь «авторизует» токен запроса на доступ к своей учетной записи.
  • Обмен токенами: клиент обменивает кратковременные временные учетные данные на долгоживущий токен.

oauth1 серверный поток

юз
источник
0

Я знаю, что вхожу в это немного поздно, но вы можете использовать wp_remote_get и _post?

Я извлекаю и публикую контент с моей установкой WordPress, используя их:

Это общая идея из кодекса WordPress:

$response = wp_remote_post( $url, array(
    'body'    => $data,
    'httpversion' => '1.0',
    'sslverify' => false,
    'headers' => array(
        'Authorization' => 'Basic ' . base64_encode( $username . ':' . $password ),
    ),
) );

Вот более конкретный пример:

$url='http://WWW.EXAMPLE HERE.';
$response = wp_remote_post( $url, array(
    'method' => 'POST',
    'timeout' => 45,
    'redirection' => 5,
    'httpversion' => '1.0', //needed to get a response
    'blocking' => true,
    'headers' => array('Authorization' => 'Basic ' . base64_encode( 'MY TOKENID' . ':' . '' )),
    'body' => $body // in array
    'cookies' => array()
    )
);

if ( is_wp_error( $response ) ) {
   $error_message = $response->get_error_message();
   echo "Something went wrong: $error_message";
} else {
 //  echo 'Response:<pre>';
 //  print_r( $response );
 //    echo '</pre>'; 
$responseBody = json_decode($response['body'],true);
echo $responseBody['message'];

    }
    }
}

Хитрость заключается в кодировании имени пользователя и pw. Теперь время, зависящее от имени пользователя API и pw, будет либо пустым, либо будет вашим токеном.

так, например, в моем конкретном примере выше, заголовки были

'headers' => array('Authorization' => 'Basic ' . base64_encode( 'MYTOKENID' . ':' . '' ))

и я оставил pw пустым. Это зависит от системы API, которую вы используете.

rudtek
источник