Как запретить доступ к wp-admin для определенных ролей пользователей?

24 сент. 2012 г., 12:59:59
Просмотры: 41.9K
Голосов: 11

Я пытался использовать плагин Front End Users, но он конфликтует с чем-то, так как блокирует доступ к некоторым страницам на фронтенде. Поэтому мне нужно вручную настроить так, чтобы любой пользователь, кроме двух определенных имен пользователей (или ролей), не мог получить доступ к wp-admin.

0
Все ответы на вопрос 6
17
19

Плагин

По сути, это просто проверка прав пользователя с последующим редиректом через вызов exit. Затем происходит перенаправление на сайт, откуда пришел запрос.

<?php
! defined( 'ABSPATH' ) AND exit;
/* Plugin Name: (#66093) »kaiser« Запрет доступа к админке для определенных ролей */


function wpse66093_no_admin_access()
{
    // Не выполнять, если пользователь вошел в систему и пытается выйти
    // Возможно, потребуется одна или две дополнительные проверки.
    // Особенно если у вас настроены кастомные правила и маршруты для входа/выхода/сброса пароля и т.д.
    if ( 
        ! is_admin()
        || (
            is_user_logged_in()
            && isset( $GLOBALS['pagenow'] ) AND 'wp-login.php' === $GLOBALS['pagenow']
        )
    ) {
        return;
    }

    $redirect = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : home_url( '/' );
    if ( 
        current_user_can( 'CAPABILITY_NAME_HERE' )
        OR current_user_can( 'CAPABILITY_NAME_HERE' )
    )
        exit( wp_redirect( $redirect ) );
}
add_action( 'admin_init', 'wpse66093_no_admin_access', 100 );

Учтите, что это будет работать только со стандартными настройками (см. комментарии в коде). Кастомная логика входа, выхода, регистрации или сброса пароля может нарушить работу плагина.

Роли vs. Права: Поскольку названия ролей могут меняться, а роли — это просто группы прав, лучше проверять конкретные права, а не названия ролей. Список встроенных ролей и прав можно найти здесь. Просто посмотрите, какие права наиболее ограничены, и найдите подходящее. Затем укажите его в коде выше. Так проще поддерживать код, если название роли изменится. Да, вы можете использовать и название роли, что будет работать в WordPress, но это может привести к трудноуловимым багам при изменении названия роли.

Примечание: Не думайте о ролях в иерархическом ключе. Представьте бухгалтера, чей email вы вводите в SaaS-системе для получения счетов. Большинство разработчиков не имеют доступа к платежным данным, а бухгалтер — к настройкам деплоя или безопасности. У них разные роли с одинаково «высокими» правами, но для совершенно разных частей системы. Держите этот пример в голове, когда пишете проверки прав или добавляете кастомные права в систему.

24 сент. 2012 г. 14:42:31
Комментарии

Так что мне нужно добавить это в начало моего файла functions.php?

Claire Claire
24 сент. 2012 г. 15:54:05

Либо где-нибудь в вашем functions.php, либо в папке плагина или mu-plugins. Поскольку это не связано с отображением контента, imho это должно быть в плагине, отсюда и заголовок плагина. Это имеет преимущество, что функциональность не теряется при смене темы. Просто измените названия ролей пользователей, загрузите и готово.

kaiser kaiser
24 сент. 2012 г. 15:59:31

Это не работает. Я изменил названия ролей пользователей на свои две роли, которые могут получить доступ. Затем я изменил его на capability, например Add users, но я всё ещё могу получить доступ к бэкенду под другой ролью пользователя

Claire Claire
24 сент. 2012 г. 18:28:36

@Nicola Существует огромная разница между меткой в интерфейсе (например: "Добавить пользователей") и реальной Ролью или Возможностью - в вашем случае add_users.

kaiser kaiser
24 сент. 2012 г. 20:07:56

Хорошо, спасибо, я попробовал приведённый выше код с add_users вместо этого, и он всё равно не работает... если я вхожу как пользователь без этой возможности, я всё равно могу перейти в wp-admin

Claire Claire
26 сент. 2012 г. 14:44:14

@Nicola Вы ознакомились со ссылкой о Ролях и Возможностях ↑ в комментарии выше? Пожалуйста, убедитесь, что пользователь действительно не имеет этой возможности.

kaiser kaiser
26 сент. 2012 г. 14:48:22

Эй, у них точно нет такой возможности. Я просто добавил код в свой файл functions.php, так как не был уверен, как сделать это плагином, который WordPress распознает. Также у меня была ошибка, где $_SERVER['HTTP_REFERER'] был неопределенным индексом, поэтому я добавил проверку if isset перед ним.

Claire Claire
26 сент. 2012 г. 15:13:39

А, понятно. Теперь мы знаем, в чем проблема: я обновил ответ, но нужно добавить это как плагин. Это плагин, он будет распознан. Я просто не добавил полный заголовок (что необязательно). Вы также можете запустить его как mu-плагин (почитайте в codex об этом). Лучше оставить его как плагин, чтобы он не потерялся при смене темы.

kaiser kaiser
26 сент. 2012 г. 15:28:01

Хорошо, можешь отредактировать его с использованием if isset, так как снова срабатывает ошибка неопределенного индекса 'HTTP_REFERER', и я не уверен в твоей логике, чтобы правильно его отредактировать.

Claire Claire
26 сент. 2012 г. 16:17:23

эй, это круто, я просто сделал перенаправление на главную страницу сайта. Теперь всё работает, спасибо!

Claire Claire
26 сент. 2012 г. 16:20:13

Снова здравствуйте, у меня есть ещё одна задача. У меня есть плагин, который позволяет пользователю обновлять свою фотографию прямо из интерфейса. Этот плагин выполняет некоторые AJAX-операции на сервере для этого.

В приведённом выше коде я предполагаю, что нужно проверить, находимся ли мы на этой странице. Однако, так как мы находимся в директории плагина, он не может определить текущую страницу через функции WordPress, поэтому я использовал $page = array_shift( explode( '?', $_SERVER['REQUEST_URI'] ) );, а затем попытался изменить код выше, добавив условие if ( current_user_can( 'add_users' ) || $page=="/your-profile/"){, но это не сработало.

Claire Claire
8 окт. 2012 г. 12:05:20

@Nicola Пожалуйста, всегда добавляйте такую информацию в первоначальный вопрос как правку, а не в комментарий здесь. Во-вторых, пожалуйста, задавайте новый вопрос, когда тема меняется или расширяется. Спасибо.

kaiser kaiser
8 окт. 2012 г. 12:07:37

Всё в порядке, я разобрался, добавив die($page) и понял, что плагин вызывается только при нажатии на редактирование профиля, в этот момент $page="/wp-admin/admin-ajax.php". Теперь всё исправлено.

Claire Claire
8 окт. 2012 г. 12:08:24

Хорошо, извините за это

Claire Claire
8 окт. 2012 г. 12:08:57

WordPress, вероятно, начнёт вызывать _doing_it_wrong() при проверке имени роли как capability в current_user_can(). См. 38653

Nathan Johnson Nathan Johnson
16 апр. 2017 г. 19:43:10

Хорошо, однако пользователи не могут выйти из системы из-за этого действия.

berend berend
29 июн. 2017 г. 13:00:03

Не забудьте проверить defined('DOING_AJAX'), если у вас есть AJAX-запросы на фронтенде, иначе они будут заблокированы!

Ste_95 Ste_95
19 авг. 2020 г. 09:46:18
Показать остальные 12 комментариев
0

Недавно пересмотрел этот ответ, так как он давно не обновлялся. Сейчас 2021 год.

Принятый ответ проверяет, является ли текущая страница страницей wp-login.php ИЛИ административной страницей ВО ВРЕМЯ использования хука admin_init, что бессмысленно.

admin_init срабатывает при инициализации административного экрана или скрипта. Он НЕ работает только на пользовательских административных экранах. Он также запускается на admin-ajax.php и admin-post.php.

Ни в коем случае он не сработает на wp-login.php, так как это НЕ административный экран. Хотя он действительно сработает при AJAX-запросе, поэтому этот случай нужно обрабатывать. wp_doing_ajax() определяет, является ли текущий запрос AJAX-запросом WordPress.

В следующем примере я использую пользовательскую способность delete_posts, чтобы разрешить доступ к бэкенду WordPress для ролей admin, editor и author. Для более строгого подхода обратитесь к Таблице возможностей и ролей.

Напоминание о стандартных ролях WordPress (Сводка ролей):

супер администратор администратор редактор автор участник подписчик.

В однопользовательской установке WordPress администраторы фактически являются супер администраторами.

Я выбрал использование wp_die() вместо простого перенаправления пользователей. wp_die() предоставляет своего рода пользовательское сопровождение, так как останавливает выполнение WordPress и отображает HTML-страницу с сообщением об ошибке. Такой же подход можно реализовать с перенаправлением пользователей на страницу 404. Любое объяснение ситуации лучше, чем слепое перенаправление на домашнюю страницу.

add_action( 'admin_init', 'restrict_wpadmin_access' );
if ( ! function_exists( 'restrict_wpadmin_access' ) ) {
    function restrict_wpadmin_access() {
        if ( wp_doing_ajax() || current_user_can( 'delete_posts' ) ) {
            return;
        } else {
            header( 'Refresh: 2; ' . esc_url( home_url() ) );
            $args = array(
                'back_link' => true,
            );
            wp_die( 'Доступ запрещён.', 'Ошибка', $args );
        };
    };
};

Чтобы предотвратить стандартное перенаправление на wp-admin.php после входа, я использую фильтр хука login_redirect, который фильтрует URL перенаправления при входе. Я перенаправляю пользователей на их собственную страницу профиля, используя get_author_posts_url(), но вы можете легко перенаправить на любую страницу. Вы также можете условно перенаправлять в зависимости от роли пользователя (например, администраторов на административную страницу, остальных на профиль), всё объяснено в разделе примеров на странице CODEX.

add_filter( 'login_redirect', 'redirect_user_to_profile_on_login', 10, 3 );
if ( ! function_exists( 'redirect_user_to_profile_on_login' ) ) {
    function redirect_user_to_profile_on_login( $redirect_to, $requested_redirect_to, $user ) {
        if ( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
            $redirect_to = esc_url( get_author_posts_url( $user->ID ) );
        };
        return $redirect_to;
    };
};
25 мар. 2021 г. 13:20:20
1

Принятый ответ упоминает Роль пользователя, но фактически использует функцию для Возможности пользователя.

Вот решение для Ролей пользователя:

 function wpse66094_no_admin_access() {
    $redirect = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : home_url( '/' );
    global $current_user;
    $user_roles = $current_user->roles;
    $user_role = array_shift($user_roles);
    if($user_role === 'YOUR_USER_ROLE_HERE'){
        exit( wp_redirect( $redirect ) );
    }
 }

add_action( 'admin_init', 'wpse66094_no_admin_access', 100 );
6 апр. 2015 г. 18:17:51
Комментарии

Вы должны проверять возможности (capabilities), а не роли. Как указано на странице CODEX функции current_user_can(): "Хотя проверка конкретных ролей вместо возможностей частично поддерживается, такая практика не рекомендуется, так как может давать ненадёжные результаты. @see https://developer.wordpress.org/reference/functions/current_user_can/#description

amarinediary amarinediary
7 янв. 2022 г. 13:16:50
0

На основе ответа, предоставленного @kaiser (спасибо, кстати), вот мой рабочий код, на случай, если кому-то он понадобится. Код размещается в файле functions.php.

Условие таково: если пользователь не может manage_options или edit_posts.

function wpse66093_no_admin_access() {
    $redirect = home_url( '/' );
    if ( ! ( current_user_can( 'manage_options' ) || current_user_can( 'edit_posts' ) ) )
        exit( wp_redirect( $redirect ) );
}
add_action( 'admin_init', 'wpse66093_no_admin_access', 100 );
4 сент. 2015 г. 12:11:25
0

Используя ответ @kaiser, я обнаружил, что вам нужно использовать хук admin_menu вместо admin_init, так как он срабатывает до проверки !user_can_access_admin_page() в wp-admin/includes/menu.php. В противном случае, если пользователь не имеет доступа 'read' к панели управления, он просто получит страницу с сообщением 'У вас недостаточно прав для доступа к этой странице.' вместо перенаправления.

8 апр. 2016 г. 03:02:38
1

Если удалить возможность read у роли, пользователь не сможет получить доступ к консоли. Он увидит следующую ошибку:

У вас недостаточно прав для доступа к этой странице админки.

Причина: текущий пользователь не имеет возможности "read", которая требуется для доступа к пункту меню "Консоль".

Ссылка: https://codex.wordpress.org/Roles_and_Capabilities#read

25 февр. 2019 г. 19:15:47
Комментарии

стоит отметить, что пользователь без прав всё равно может успешно войти в систему, и панель администратора отображается.

kubi kubi
20 мая 2020 г. 16:29:19