Как сгенерировать HMAC-SHA1 подпись для использования с WP REST API и OAuth1

Вопрос или проблема

Я пытаюсь опубликовать пост, используя 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.

Оцените материал
Добавить комментарий

Капча загружается...