Как создать прокси-сервер для REST API в WordPress
В современных проектах на WordPress часто возникает необходимость взаимодействия с внешними REST API. Однако прямые запросы с фронтенда могут быть ограничены политиками CORS, а также требуют дополнительной защиты и централизованной обработки данных. В этой статье мы рассмотрим, как с помощью WordPress создать прокси-сервер для REST API, позволяющий безопасно и эффективно работать с внешними API через собственный эндпоинт.
Что такое прокси-сервер для REST API и зачем он нужен
Прокси-сервер REST API — это промежуточный сервер, который принимает запросы от клиента, перенаправляет их к внешнему API, получает ответы и передает их обратно клиенту. Такое решение полезно для:
- Обхода ограничений CORS, когда браузер блокирует прямые запросы к внешнему API.
- Централизованного контроля и кэширования данных.
- Поддержания безопасности — скрытия ключей API и токенов от клиента.
- Обработки и трансформации данных перед отправкой на фронтенд.
В WordPress мы можем реализовать прокси через создание кастомного REST API эндпоинта.
Создание прокси REST API эндпоинта в WordPress
Для начала зарегистрируем новый маршрут в WordPress REST API, который будет принимать запросы и перенаправлять их к внешнему API. Ниже пример кода, который добавляем в файл плагина или в functions.php темы:
add_action('rest_api_init', function () {
register_rest_route('wpapi/v1', '/proxy', array(
'methods' => 'POST',
'callback' => 'wpapi_proxy_rest_api_callback',
'permission_callback' => '__return_true', // Можно доработать проверку
));
});
function wpapi_proxy_rest_api_callback(\WP_REST_Request $request) {
$params = $request->get_json_params();
if (empty($params['url'])) {
return new \WP_REST_Response(['error' => 'URL is required'], 400);
}
$url = esc_url_raw($params['url']);
$method = isset($params['method']) ? strtoupper($params['method']) : 'GET';
$body = isset($params['body']) ? $params['body'] : null;
// Разрешённые домены для проксирования
$allowed_domains = ['api.example.com', 'another.api.com'];
$host = parse_url($url, PHP_URL_HOST);
if (!in_array($host, $allowed_domains)) {
return new \WP_REST_Response(['error' => 'Domain not allowed'], 403);
}
$args = [
'method' => $method,
'timeout' => 15,
'headers' => [
'Accept' => 'application/json',
],
];
if ($body && in_array($method, ['POST', 'PUT', 'PATCH'])) {
$args['body'] = is_array($body) ? json_encode($body) : $body;
$args['headers']['Content-Type'] = 'application/json';
}
$response = wp_remote_request($url, $args);
if (is_wp_error($response)) {
return new \WP_REST_Response(['error' => 'Request failed: ' . $response->get_error_message()], 500);
}
$code = wp_remote_retrieve_response_code($response);
$data = wp_remote_retrieve_body($response);
// Возвращаем ответ клиенту
return new \WP_REST_Response(json_decode($data, true), $code);
}В этом примере мы принимаем POST-запрос на /wp-json/wpapi/v1/proxy с JSON-телом, содержащим параметры url, method и body. Функция проверяет, что домен входит в список разрешённых, затем делает запрос к внешнему API и возвращает ответ.
Безопасность и ограничения
Очень важно ограничивать домены, к которым разрешено проксирование, чтобы предотвратить SSRF-атаки. В примере используется массив $allowed_domains, который нужно настроить под ваши нужды.
Также можно добавить аутентификацию — например, проверять nonce, права пользователя, или токены в заголовках. В этом примере permission_callback возвращает true для упрощения.
Как использовать прокси-эндпоинт на фронтенде
На стороне клиента можно обращаться к прокси следующим образом (пример на JavaScript с использованием fetch):
fetch('/wp-json/wpapi/v1/proxy', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://api.example.com/data',
method: 'GET'
})
})
.then(response => response.json())
.then(data => console.log('Полученные данные:', data))
.catch(error => console.error('Ошибка:', error));Такой подход позволяет скрыть ключи и токены API, а также централизовать обработку ответов.
Использование плагина Clearfy Pro для улучшения безопасности REST API
Для усиления безопасности вашего прокси и общего REST API можно использовать плагин Clearfy Pro. Он позволяет настроить ограничения доступа, скрыть ненужные эндпоинты и добавить дополнительные фильтры безопасности.
Настройка Clearfy Pro для REST API
После установки и активации Clearfy Pro в разделе настроек выберите параметры, связанные с REST API, и включите блокировку нежелательных запросов. Это поможет защитить ваш сайт от сканирования и атак.
Кэширование ответов прокси для повышения производительности
Если внешнее API не требует мгновенной актуализации данных, можно добавить кэширование ответов, чтобы снизить нагрузку и ускорить ответы. Для этого удобно использовать Transients API WordPress.
function wpapi_proxy_rest_api_callback(\WP_REST_Request $request) {
$params = $request->get_json_params();
$url = esc_url_raw($params['url']);
$cache_key = 'wpapi_proxy_' . md5($url);
$cached = get_transient($cache_key);
if ($cached !== false) {
return new \WP_REST_Response(json_decode($cached, true), 200);
}
// ... код запроса к внешнему API как выше ...
$response = wp_remote_get($url);
if (is_wp_error($response)) {
return new \WP_REST_Response(['error' => $response->get_error_message()], 500);
}
$body = wp_remote_retrieve_body($response);
set_transient($cache_key, $body, 3600); // кэш на 1 час
return new \WP_REST_Response(json_decode($body, true), 200);
}Таким образом, повторные запросы к одному и тому же URL будут обслуживаться из кэша, что значительно повысит производительность.
Выводы и рекомендации
Создание собственного прокси-сервера для REST API в WordPress — простой и эффективный способ решить многие проблемы интеграции с внешними сервисами. Такой подход помогает обходить ограничения CORS, скрывать ключи API, централизованно обрабатывать данные и улучшать безопасность.
Обязательно учитывайте вопросы безопасности, ограничивайте доступ и домены, используйте проверку прав и кеширование. Для расширенной защиты рассмотрите использование плагина Clearfy Pro.
Этот подход подойдет как для небольших проектов, так и для крупных сайтов с активным взаимодействием с внешними API.