Вопрос или проблема
Я пытаюсь опубликовать пост, используя WP REST API. Мне удалось аутентифицироваться с помощью OAuth1, используя http-клиент PAW. Я также смог опубликовать пост на сайте (снова с помощью PAW).
PAW сгенерировал для меня PHP-код, который я могу использовать на своем сайте. Я создал test.php и вставил код туда. Пытался открыть страницу в браузере. Аутентификация не проходила. В первый раз говорилось, что подпись недействительна, в другой раз, что временная метка недействительна, а еще раз, что nonce недействителен.
Я проверил в PAW и обнаружил, что при каждом новом запуске PAW генерирует уникальный nonce, временную метку и подпись HMAC-SHA1 — но код, который я использую, содержит одно и то же значение nonce, временную метку и подпись HMAC-SHA1 на каждом запуске. Я думаю, что мне нужно найти способ автоматически генерировать уникальные nonce, временные метки и подписи.
Может кто-нибудь помочь мне?
Ниже приведен код:
<?php
// Получить ресурс cURL
$ch = curl_init();
// Установить URL
curl_setopt($ch, CURLOPT_URL, 'http://sitename.com/wp-json/wp/v2/posts');
// Установить метод
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
// Установить опции
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Установить заголовки
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: OAuth oauth_consumer_key=\"zfksKSt8m7Bk\", oauth_nonce=\"dWXo8bGuKTMEqbmLf8cwqcWjfjDyqwKh\", oauth_signature=\"%2BOy0fDsKilNymYOOZRqjJN5q3tg%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1468900106\", oauth_token=\"IG6x6jIjboVhmyzFtjzn1fGT\", oauth_version=\"1.0\"",
"Content-Type: application/json; charset=utf-8",
]
);
// Создать тело
$json_array = [
"title" => "Это будет новый пост"
];
$body = json_encode($json_array);
// Установить тело
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
// Отправить запрос и сохранить ответ в $resp
$resp = curl_exec($ch);
if(!$resp) {
die('Ошибка: "' . curl_error($ch) . '" - Код: ' . curl_errno($ch));
} else {
echo "Код состояния HTTP-ответа: " . curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "\nТело HTTP-ответа: " . $resp;
}
// Закрыть запрос, чтобы очистить некоторые ресурсы
curl_close($ch);
У меня такая же проблема, но для автоматической генерации времени и nonce вы можете сделать так:
<?php
$nonce = md5(mt_rand());
// Установить заголовки
curl_setopt($ch, CURLOPT_HTTPHEADER, ['
Authorization: OAuth oauth_consumer_key="zfksKSt8m7Bk",
oauth_nonce=".$nonce.",
oauth_signature="%2BOy0fDsKilNymYOOZRqjJN5q3tg%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp='.time().',
oauth_token="IG6x6jIjboVhmyzFtjzn1fGT",
oauth_version="1.0"
',
'Content-Type: application/json; charset=utf-8',
]
);
Я изучаю, как генерировать подпись. Я думаю, это может быть полезно сгенерировать подпись с помощью чего-то подобного
$signature = hash_hmac( 'sha1', $base_string, $key );
Ответ или решение
Для успешной публикации постов через WP REST API с использованием OAuth1 и HMAC-SHA1 подписи необходимо правильно генерировать уникальные значения nonce, timestamp и саму подпись для каждой запроса. В этой инструкции мы поэтапно разберем, как это сделать на PHP.
Шаг 1: Подготовка параметров
Первое, что вам нужно сделать, это сгенерировать уникальные значения nonce
и timestamp
. Для nonce
рекомендуется использовать функцию генерации случайных данных, например, md5(mt_rand())
, а timestamp
можно получить с помощью time()
.
Шаг 2: Формирование базовой строки (base string)
Base string формируется из метода HTTP, URL и параметров запроса. Этот шаг критически важен для правильной генерации подписи. Пример формирования base string:
$method = 'POST';
$url = 'http://sitename.com/wp-json/wp/v2/posts';
$parameters = [
'oauth_consumer_key' => 'zfksKSt8m7Bk',
'oauth_nonce' => $nonce,
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => $timestamp,
'oauth_token' => 'IG6x6jIjboVhmyzFtjzn1fGT',
'oauth_version' => '1.0'
];
// Для формирования base string, сначала отсортируйте параметры в алфавитном порядке
ksort($parameters);
$parameters = http_build_query($parameters);
$base_string = $method . '&' . rawurlencode($url) . '&' . rawurlencode($parameters);
Шаг 3: Генерация подписи (signature)
С помощью HMAC-SHA1 подписи мы заверяем наш запрос. Для этого нужно подготовить секретный ключ, который состоит из вашего oauth_consumer_secret
и oauth_token_secret
, соединенных знаком &
.
$consumer_secret = 'your_consumer_secret'; // Замените на ваш секретный ключ
$token_secret = 'your_token_secret'; // Замените на ваш токен секрет
$key = rawurlencode($consumer_secret) . '&' . rawurlencode($token_secret);
$signature = base64_encode(hash_hmac('sha1', $base_string, $key, true));
Шаг 4: Подготовка заголовков запроса
Теперь, когда у вас есть все необходимые компоненты, вы можете подготовить заголовок для вашего запроса:
$headers = [
"Authorization: OAuth
oauth_consumer_key=\"zfksKSt8m7Bk\",
oauth_nonce=\"{$nonce}\",
oauth_signature=\"{$signature}\",
oauth_signature_method=\"HMAC-SHA1\",
oauth_timestamp=\"{$timestamp}\",
oauth_token=\"IG6x6jIjboVhmyzFtjzn1fGT\",
oauth_version=\"1.0\"",
"Content-Type: application/json; charset=utf-8"
];
Шаг 5: Отправка запроса с cURL
Используйте cURL для отправки вашего запроса с созданными заголовками и телом запроса:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$json_array = [
'title' => 'Это новый пост'
];
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($json_array));
$response = curl_exec($ch);
if (!$response) {
echo 'Ошибка: "' . curl_error($ch) . '" - Код: ' . curl_errno($ch);
} else {
echo "HTTP код ответа: " . curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "\nТело ответа: " . $response;
}
curl_close($ch);
Заключение
При каждом выполнении этого кода уникальные nonce
и timestamp
генерируются заново, а также создаётся новая подпись. Это гарантирует успешную авторизацию вашего запроса. Убедитесь, что вы используете правильные секретные ключи и токены. Надеюсь, это объяснение поможет вам решить вашу задачу по работе с WP REST API и OAuth1.