Перевірка прав

Щоб запобігти зміні налаштувань плагіна або заборонити переглядати дані, доступу до яких у користувача немає, потрібно перевіряти права користувача, здійснювати будь-яку дію.

У WordPress для цього є два підходи:

  1. перевірка можливостей (прав) користувача.
  2. одноразові числа (nonce).

Це різні підходи та одноразові числа, як правило, доповнюють перевірку прав.

У цьому розділі поговоримо про перший: «Перевірка прав користувача».

Можливості користувача (перевірка прав)

Перевірка прав – це основний і мабуть фундаментальний момент у захисті та безпеці плагіна. Він перевіряє можливість користувача робити щось. У кожного користувача є роль (Підписчик, Автор, Редактор) і кожна роль має набір прав. За допомогою функції current_user_can() ми можемо перевірити, чи має поточний користувач зазначене право, наприклад manage_options(право адміністратора змінювати опції сайту). Якщо користувач має право, то функція поверне true і умова для виконання якогось коду буде виконано і навпаки – якщо права немає, код виконуватися не буде.

Наприклад, автор може публікувати та редагувати записи, але не має права редагувати чужі записи. А «Редактор» може публікувати та змінювати свої та чужі записи. Але жоден з них не може змінювати налаштування сайту, як це може робити адміністратор. Залежно від можливостей кожної ролі, адмін-панель WordPress виглядатиме по-різному: наприклад, у «Автора» будуть одне меню, а у «Адміністратора» воно буде інше – значно розширено.

Список усіх прав, залежно від ролі користувача, ви знайдете в описі функції current_user_can() .

Перевірка прав користувача на прикладі

При створенні плагіна, потрібно приділяти пильну увагу ролям, яким мають бути дозволені виконання певних дій.

Наприклад, давайте подивимося на небезпечний код без перевірки прав і що поганого в результаті може вийти. Приклад нижче показує функцію, яка, за задумом, повинна давати можливість «Редактору» видаляти записи на фронтенді сайту:

## функція виводить посилання на видалення поточного запису
function frontend_delete_link(){
	$url = add_query_arg(
		array( 'action'=> 'frontend_delete_link', 'post'=> get_the_ID() ),
		home_url(),
	);

	echo "<a href='{$url}'>Видалити</a>";
}

Тепер уявимо, ми використали цю функцію і вивели посилання десь у фронті. При натисканні на неї спрацьовуватиме наступний код обробки запиту видалення запису:

## Функція видаляє вказаний у $_REQUEST['post'] запис
function frontend_delete_post(){

	// Визначимо ID запису
	$post_id = ( isset( $_REQUEST['post'] ) ? get_post( (int) $_REQUEST['post'] ) : false;

	// Немає запису - виходимо...
	if( empty($post_id) ) return;

	// Видаляємо запис
	wp_trash_post($post_id);

	// Перенаправляємо на сторінку адмінки
	$redirect = admin_url('edit.php');
	wp_safe_redirect ($ redirect);
	exit;
}

// Включаємо обробник
if( isset($_REQUEST['action']) && $_REQUEST['action']=='frontend_delete_link' ) {
	add_action('init', 'frontend_delete_post');
}

Код вище дозволяє будь-якому відвідувачу сайту, натиснути на посилання “Видалити” та видалити пост. А треба, щоб таку можливість мали користувачі за участю «Редактор» або старшою роллю, наприклад, «Адміністратор». Якщо будь-хто зможе це зробити, то ви зрештою залишитеся без контенту.

Для цього давайте змінимо код посилання і не виводитиме посилання для ролей молодше редактора:

function frontend_delete_link(){
	// виходимо якщо немає права 'edit_others_posts', яке має Редактори і старші ролі.
	if( ! current_user_can( 'edit_others_posts' ) ) return;

	$url = add_query_arg(
		array( 'action'=> 'frontend_delete_link', 'post'=> get_the_ID() ),
		home_url(),
	);

	echo "<a href='{$url}'>Видалити</a>";
}

Також таку перевірку потрібно додати під час виконання самої операції видалення:

## Функція видаляє вказаний у $_REQUEST['post'] запис
function frontend_delete_post(){

	// Визначимо ID запису
	$post_id = ( isset( $_REQUEST['post'] ) ? get_post( (int) $_REQUEST['post'] ) : false;

	// Немає запису - виходимо...
	if( empty($post_id) ) return;

	// виходимо якщо немає права 'edit_others_posts', яке має Редактори і старші ролі.
	if( ! current_user_can( 'edit_others_posts' ) ) return;

	// Видаляємо запис
	wp_trash_post($post_id);

	// Перенаправляємо на сторінку адмінки
	$redirect = admin_url('edit.php');
	wp_safe_redirect ($ redirect);
	exit;
}

// Включаємо обробник
if( isset($_REQUEST['action']) && $_REQUEST['action']=='frontend_delete_link' ) {
	add_action('init', 'frontend_delete_post');
}

В обох випадках ми підтверджуємо, що поточний користувач має можливість edit_others_posts, яка може бути лише у «Редакторів» або ролей старших. Якщо такої можливості немає, ми нічого не робимо.

Логіка перевірки прав досить проса і зрозуміла. Варіантів де це потрібно дуже багато. І майже завжди використовується функція current_user_can() .

Одноразові числа

Перевірка прав – це перший та основний рівень захисту. Він дозволяє або забороняє поточному користувачеві заходити на сторінки, бачити частини контенту та виконувати будь-які дії. Але такий захист не ідеальний… Чому? Читайте у розділі «Одноразові числа» .

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *