Как сделать JWT-аутентифицированные запросы к WordPress API
Это не совсем вопрос, а скорее руководство о том, как делать аутентифицированные запросы к WordPress API используя JWT. Я пишу это как памятку для себя и для тех, кому может понадобиться помощь с этой темой.

Почему JWT аутентификация
Я разрабатываю сайт, использующий WordPress в качестве бэкенда и React+Redux приложение для фронтенда, поэтому весь контент я получаю на фронтенде, делая запросы к WordPress API. Некоторые запросы (в основном POST) требуют аутентификации, и именно тогда я столкнулся с JWT.
Что нам нужно
Для использования JWT аутентификации с WordPress сначала необходимо установить плагин JWT Authentication for WP REST API. Как указано в инструкциях плагина, нам также потребуется изменить некоторые основные файлы WordPress. В частности:
В файле .htaccess, расположенном в корневой папке установки WordPress, нужно добавить следующие строки:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
В файле wp-config.php, также находящемся в корневой папке WordPress, необходимо добавить следующие строки:
define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key'); // Замените 'your-top-secret-key' на реальный секретный ключ.
define('JWT_AUTH_CORS_ENABLE', true);
Проверка доступности JWT
Чтобы убедиться, что JWT теперь доступен, откройте Postman и сделайте запрос к стандартному 'индексу' WordPress API:
http://example.com/wp-json/
В ответе должны появиться новые эндпоинты, такие как /jwt-auth/v1
и /jwt-auth/v1/token
. Если вы видите их в ответе, значит JWT работает.
Получение JWT токена
Останемся в Postman и запросим токен у WordPress API:
http://example.com/wp-json/jwt-auth/v1/token
В ответе вы получите JWT токен — зашифрованный ключ, который выглядит примерно так:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODg4OFwvZm90b3Jvb20tbmV4dCIsImlhdCI6MTUyMjU5NzQ1MiwibmJmIjoxNTIyNTk3NDUyLCJleHAiOjE1MjMyMDIyNTIsImRhdGEiOnsidXNlciI6eyJpZCI6IjEifX19.hxaaT9iowAX1Xf8RUM42OwbP7QgRNxux8eTtKhWvEUM
Выполнение аутентифицированного запроса
Давайте попробуем изменить заголовок поста с ID 300 в качестве примера аутентифицированного запроса с JWT.
В Postman выберите метод POST и введите следующий эндпоинт:
http://example.com/wp-json/wp/v2/posts/300
Выберите No Auth во вкладке Authorization и добавьте следующее во вкладке Headers:
'Content-type': 'application/json',
'Authorization': 'Bearer jwtToken' // Замените jwtToken на реальный токен (зашифрованный ключ выше)
Наконец, во вкладке Body выберите raw и JSON (application/json), затем в редакторе введите следующее:
{ "title": "ДА! Аутентифицированные запросы с JWT работают" }
Теперь можно нажать SEND. Проверьте вкладку response: значение ключа title должно измениться на ДА! Аутентифицированные запросы с JWT работают
.

Как бы вы различали вызовы, которые должны быть аутентифицированы, и те, которые не требуют аутентификации на стороне бэкенда?

Я также разрабатываю React-приложение, которое получает данные записей из базы данных WordPress через WordPress REST API, но я не хочу, чтобы конечные точки REST API были общедоступными. Есть ли способ ограничить доступ к REST API, кроме как для моего React-приложения?

@chris Если вы хотите скрыть свои конечные точки от неавторизованных запросов, добавьте их под пространство имен jwt_auth, например так: register_rest_route( 'jwt-auth/v1', 'your_custom_endpoint ...
. Любые запросы к /jwt-auth/ будут требовать авторизации

@uruk как только у вас есть JWT токен, я думаю, вы всегда можете его отправлять, поэтому вам не нужно различать, какой из них нужен, а какой нет.

Насколько я вижу, этот плагин так давно не обновлялся, безопасно ли его использовать?

@Lai32290 Этот плагин выглядит обновленным и, похоже, основан на плагине, упомянутом в этом вопросе: https://wordpress.org/plugins/jwt-auth/

@uruk вот как я реализовал различие между вызовами, которые требуют аутентификации, и теми, которые не требуют, без использования плагина: Как принудительно включить аутентификацию в REST API для страницы с парольной защитой, используя кастомную таблицу и fetch() без плагина

Дополняя ответ @grazianodev, вот как можно получить токен авторизации с помощью cURL:
/**
* Генерация JWT токена для последующих вызовов API WordPress
*/
private function getToken() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://site.localhost/wp-json/jwt-auth/v1/token');
curl_setopt($ch, CURLOPT_POST, 1);
# Учетные данные администратора
curl_setopt($ch, CURLOPT_POSTFIELDS, "username=admin&password=Str0ngPass");
// Получаем ответ сервера ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
if ($server_output === false) {
die('Ошибка при получении JWT токена WordPress для интеграции с API.');
}
$server_output = json_decode($server_output);
if ($server_output === null && json_last_error() !== JSON_ERROR_NONE) {
die('Неверный ответ при получении JWT токена WordPress для интеграции с API.');
}
if (!empty($server_output->token)) {
$this->token = $server_output->token; # Токен здесь
curl_close ($ch);
return true;
} else {
die('Неверный ответ при получении JWT токена WordPress для интеграции с API.');
}
return false;
}
После этого отправляйте запросы с заголовком: "Authorization: Bearer $token"
Где $token - это токен, возвращаемый функцией getToken() выше.
Лично я использую плагин "Disable REST API and Require JWT / OAuth Authentication" для ограничения доступа к API только с указанным выше токеном.
