قابلیت REST API در وردپرس این امکان را به ابزارها و افزونه های سوم شخص می دهد که بدون دسترسی مستقیم به دیتابیس سایت وردپرسی ما، اطلاعاتی را از وردپرس درخواست کرده و آنها را در فرمت json دریافت کنند. گاهی اوقات این اطلاعات آنقدر سنگین هستند که باعث کاهش شدید سرعت لودینگ سایت شما می شوند. در برخی موارد که شما نمی دانید این APIها توسط چه ابزاری درخواست و اجرا میشوند، می توانید به طور کامل قابلیت API را غیرفعال کنید تا دیگر افزونه ای یا ابزاری قادر به دریافت اطلاعات نباشد. در این تاپیک از انجمن بی تاک قصد داریم روشی برای غیرفعال کردن این قابلیت وردپرس به شما معرفی کنیم.

اگر از ابزارهایی مانند GTmetrix استفاده کرده باشید، در قسمت Waterfall می توانید آدرس هایی را ببینید که هنگام اجرا شدن سایت، اطلاعات را به سرور ارسال و از آن دریافت می کنند. مانند:
https://www.example.org/wp-json/wp/v2/users
که این آدرس همان Rest API است و در اکثر مواقع به دلیل نادرست بودن کدهای درخواست اطلاعات، باعث کندی سرعت سایت می شود.
قدم اول: تعریف دستورات
برای شروع، این کد را در فایل functions.php
قالبتان قرار دهید:
define('HW_REST_API_DEFAULT_IP_WHITELIST', array('127.0.0.1', '::1'));
function hw_completely_disable_rest_api() {
if (!defined('HW_IS_REST_API_DISABLED')) {
define('HW_IS_REST_API_DISABLED', true);
}
}
function hw_disable_rest_api_user_enumeration() {
if (!defined('HW_IS_REST_API_USER_ENUMERATION_DISABLED')) {
define('HW_IS_REST_API_USER_ENUMERATION_DISABLED', true);
}
}
function hw_request_block_ip($ip_address = '') {
if (empty($ip_address)) {
$ip_address = sanitize_text_field($_SERVER['REMOTE_ADDR']);
}
if (!empty($ip_address)) {
// error_log('Blocking IP: ' . $ip_address);
$is_fail2ban_enabled = true;
if (defined('HW_REST_IS_FAIL2BAN_ENABLED') && (HW_REST_IS_FAIL2BAN_ENABLED !== true)) {
$is_fail2ban_enabled = false;
}
if ($is_fail2ban_enabled) {
openlog('wp(' . sanitize_text_field($_SERVER['HTTP_HOST']) . ')', LOG_NDELAY | LOG_PID, LOG_AUTH);
syslog(LOG_INFO, "REST User Enum " . $ip_address);
closelog();
} else {
error_log('Found enumeration attempt, but HW_REST_IS_FAIL2BAN_ENABLED is not enabled.');
}
}
}
function hw_rest_api_init() {
$is_rest_api_available = true;
$is_attempting_user_enumeration = false;
$is_user_an_administrator = false;
if ($is_user_authenticated = is_user_logged_in()) {
$is_user_an_administrator = current_user_can('administrator');
}
$is_user_authorised = ($is_user_authenticated && $is_user_an_administrator);
$is_remote_ip_whitelisted = false;
if (defined('HW_REST_API_IP_WHITELIST') && is_array(HW_REST_API_IP_WHITELIST)) {
$is_remote_ip_whitelisted = in_array($_SERVER['REMOTE_ADDR'], HW_REST_API_IP_WHITELIST);
} elseif (defined('HW_REST_API_DEFAULT_IP_WHITELIST') && is_array(HW_REST_API_DEFAULT_IP_WHITELIST)) {
$is_remote_ip_whitelisted = in_array($_SERVER['REMOTE_ADDR'], HW_REST_API_DEFAULT_IP_WHITELIST);
} else {
// ...
}
$is_ip_block_requested = false;
$is_rest_api_disabled = false;
if (defined('HW_IS_REST_API_DISABLED')) {
$is_rest_api_disabled = (HW_IS_REST_API_DISABLED === true);
}
$is_public_user_enumeration_disabled = true;
if (defined('HW_IS_REST_API_USER_ENUMERATION_DISABLED') && (HW_IS_REST_API_USER_ENUMERATION_DISABLED !== true)) {
$is_public_user_enumeration_disabled = false;
}
$is_endpoint_blocked = false;
if (!$is_user_authenticated && !$is_remote_ip_whitelisted && $is_public_user_enumeration_disabled) {
$prefix = rest_get_url_prefix();
$users_path = '/' . $prefix . '/wp/v2/users';
if ((isset($_SERVER['REQUEST_URI']) && (strpos($_SERVER['REQUEST_URI'], $users_path) !== false))
||
(isset($_REQUEST['rest_route']) && (strpos($_SERVER['rest_route'], $users_path) !== false))
) {
$is_endpoint_blocked = true;
$is_ip_block_requested = true;
}
}
$http_error_code = null;
$is_rest_api_available = false;
if ($is_user_authorised) {
// ...
} elseif ($is_remote_ip_whitelisted) {
// ...
} elseif ($is_rest_api_disabled) {
$http_error_code = 404;
} elseif (!$is_endpoint_blocked) {
// ...
} else {
$http_error_code = 404;
}
if ($is_ip_block_requested) {
hw_request_block_ip();
}
if ($http_error_code == 404) {
header("Status: 404 Not Found");
$GLOBALS['wp_query']->set_404();
status_header(404);
nocache_headers();
include get_query_template('404');
exit;
} elseif (!empty($http_error_code)) {
http_response_code($http_error_code);
die('ERR: ' . $http_error_code);
} else {
// OK.
}
}
add_action('rest_api_init', 'hw_rest_api_init', 100);
قدم دوم: مسدود سازی
مسدودسازی کامل
در این حالت، دسترسی به API را برای کاربرانی که وارد حساب خود نشده اند مسدود می کنیم اما همچنان کاربرانی که وارد سایت شده اند می توانند از REST API استفاده کنند. کافیست این کد را در فایل functions.php
قالبتان اضافه کنید:
hw_completely_disable_rest_api();
دسترسی به افزونه ها
اگر قصد دارید API را غیرفعال کنید، با روش های بالا افزونه هایی مانند Contct Form 7 که اطلاعات JSON نیاز دارند هم از کار خواهند افتاد. می توانید دسترسی افزونه ها را به REST API بدهید و مابقی را غیرفعال کنید. کافیست بجای کد بالا از این کد استفاده کنید:
hw_disable_rest_api_user_enumeration();
اجازه به یک آی پی خاص!
اگر قصد دارید کل API را غیرفعال کنید اما یک آی پی خاص دسترسی داشته باشد، می توانید از این کد استفاده کنید:
const HW_REST_API_IP_WHITELIST = array('127.0.0.1', '::1');