Как определенным группам пользователей закрыть доступ к конкретным страницам админки WordPress?

Полгода назад я писал статью о том, как полностью закрыть доступ в админку WordPress, теперь я покажу, как блокировать конкретные страницы.

Рассмотрим тут два варианта — перенаправление на другую страницу и вывод стандартного вордпрессовского сообщения об ошибке.

Редирект на другую страницу

Если у пользователя будет недостаточно прав для доступа к странице, его просто будет перекидывать в консоль (на главную) админ-панели.

function true_block_admin_pages_redirect() {
	global $pagenow;
	// тут перечисляем в массиве страницы, которые хотим скрыть, я например закрыл весь раздел меню "Плагины"
	$pages_to_block = array(
		'plugins.php',
		'plugin-install.php',
		'plugin-editor.php'
	);
	if(in_array($pagenow, $pages_to_block)){
		// указываем URL, на который будем перенаправлять тех, у кого нет доступа, в данном случае - главная страница админки
		wp_redirect( admin_url('/') );
		exit;
	}
}
 
// в этом условии необходимо перечислить права, которые необходимо иметь пользователю, чтобы получить доступ
// удалите условие, если нужно закрыть страницы для всех
if(!current_user_can('administrator')){
	add_action('admin_init', 'true_block_admin_pages_redirect');
}

Вы также можете не просто закрыть доступ к каким-то конкретным страницам в админке, но и
удалить из меню пункты, соответствующие им.

Вывод сообщения об ошибке

Вместо того, чтобы просто редиректить непонимающего пользователя на другую страницу, можно вывести определенное сообщение, объясняющее что к чему.

сообщение об ошибке доступа

В этом примере я полностью (для администраторов тоже) блокирую доступ к странице с комментами:

function true_block_admin_pages_error() {
	global $pagenow;
	$pages_to_block = array(
		'edit-comments.php'
	);
	if(in_array($pagenow, $pages_to_block)){
		// внутри скобок, в кавычках, указываем своё сообщение, HTML поддерживается
		wp_die('Прости, доступ к этой странице для тебя закрыт. <a href="' .admin_url('/'). '">Вернуться в админку.</a>');
		exit;
	}
}
 
add_action('admin_init', 'true_block_admin_pages_error');

Весь код нужно вставлять в functions.php вашей темы.

Подпишитесь, чтобы раз в неделю получать свежие статьи с блога по email.

Смотрите также

Комментарии 27

  • Даниил1 января 2013 в 16:01 #

    Спасибо!
    Мне помогла эта статья

  • Сергей13 января 2013 в 14:01 #

    Здравствуйте. Я извиняюсь, может вы знаете, как совсем закрыть доступ, я имею ввиду саму форму регистрации, если скажем кто-то набирает http://site.ru/wp-admin, чтобы его перекидывало на главную страницу, а админ мог зайти. запрет в .htaccess не канает, ip динамический.
    Заранее благодарен.

    • Миша13 января 2013 в 18:01 #

      ну а если не по IP то как ещё определять то, что зашел админ? кукисы не вариант же)

  • Сергей13 января 2013 в 18:01 #

    ну я не знаю, перенаправлением? допустим я пишу http://site.ru/sergei, а меня перебрасывает на http://site.ru/wp-admin. на joomla например, есть плагин jSecure Authentication. я просто хотел узнать, может вы знаете какое нибудь решение? Если нет, то нет. извиняюсь за назойливость. :)

    • Миша13 января 2013 в 21:01 #

      да-да в джумле был какой-то плагин, он показывал админку, только если в конце добавить ключевое слово))

      решений готовых не знаю (возможно прост не интересовался ими особо, например у меня админка заблочена паролем через .htpasswd и .htaccess, меня устраивает)

      но уверен, что можно написать такой функционал)

    • Миша13 января 2013 в 21:01 #

      ну короче в любом случае что-то с кукисами или сессиями надо мутить будет)

  • Сергей14 января 2013 в 04:01 #

    Меня устроило бы любое решение, постоянно кто-то ломится в админку, пока помогает плагин Login LockDown, хотел бы совсем лишить всех любопытных :) ,возможности даже попытаться войти. Большое спасибо, что откликнулись.

    • Миша14 января 2013 в 05:01 #

      ну вот, запоролить через .htpasswd и будет норм)у меня пока что нет статьи на эту тему, в двух словах:

      1. нужно создать в wp-admin файл .htaccess и вписать туда

      AuthType Basic
      AuthName "Какое-нибудь сообщение"
      AuthUserFile тут_полный_путь/wp-admin/.htpasswd
      require valid-user

      2. в этой же папке создаем .htpasswd
      содержимое будет следующее

      логин:пароль

      пароль должен быть в закодированном виде. вот и всё)

      • Сергей14 января 2013 в 07:01 #

        Доброе утро, Михаил. К сожалению я туповат от природы :) , поэтому у меня еще вопрос. Как мне после всего проделанного, самому попасть в админку и как закодировать пароль?
        Наверно я вам надоел уже, чувствую себя полным идиотом. Просто с .htaccess я совсем не знаком.

      • Миша14 января 2013 в 07:01 #

        Доброе утро)

        Как мне после всего проделанного, самому попасть в админку

        после первоначального ввода пароля он будет сохраняться до конца сессии, то есть его не придется вводить каждый раз, обновляя страницу в админке + например Google Chrome его может и запомнить ко всему прочему.

        и как закодировать пароль?

        я хотел сам написать такой инструмент - именно поэтому я затянул с постом на эту тему) где кодировал сам, я и не помню, например можно попробовать вот тут: http://www.psu.edu/dept/itscss/publish/htpasswd/htpasswd.html

  • Сергей14 января 2013 в 07:01 #

    Спасибо за разъяснение. Буду пробовать вечером, на работу нужно бежать. По результатам отпишусь. Еще раз огромное спасибо.

  • Антон Вихров26 октября 2013 в 22:10 #

    Миша, помогите. Все мозги уже себе изтрахал. Дело в том, что никак не могу отрубить АВТОРАМ вход на комментарии. Даже плагином adminimize убираю все лишнее, но стандартным "логином" высвечивается у них сслыка на стр с комментариями. Может быть поможете, как отрубить чтобы никто кроме администратора не могли шариться по премодерациям?

    • Миша27 октября 2013 в 12:10 #

      Прошу прощения, я удалил несколько ваших агрессивных и не содержащих смысла комментов. Конечно, не всегда всё получается но бессмысленно винить в этом кого-то кроме себя.

      Коды из данного поста работают, я убедился в этом сам и ещё несколько людей с прямыми руками.

      Итак, как отрубить авторам вход на комментарии. Вот так:

      function true_block_admin_pages_redirect() {
      	global $pagenow;
      	$pages_to_block = array(
      		'edit-comments.php'
      	);
      	if(in_array($pagenow, $pages_to_block)){
      		wp_die('Прости, доступ к этой странице для тебя закрыт. <a href="' .admin_url('/'). '">Вернуться в админку.</a>');
      		exit;
      	}
      }
       
      if(current_user_can('author')){
      	add_action('admin_init', 'true_block_admin_pages_redirect');
      }

      Хочу также заметить, что авторы могут модерировать только те комменты, которые оставлены к их собственным записям.

  • Liza9 декабря 2013 в 17:12 #

    Здрасти Помогите закрыть страницу от пользователей вообще заблокировать
    Возможно сделать правильный редирект с файлом .htaccess

    Например мне нужно сделать редирект с ссылки поддомена с этой странице __http://music.site.com/search/Showtek+Feat.+We+Are+Loud+%26+Sonny+Wilson+-+Booyah+(Original+Mix)

    на главную поддоменена http://music.site.com или даже 410 отдавала тоже хорошо, главное что бы переход на эту страницу не возможно было перейти

    Сделал вот так не сработало Redirect 301 music.site.com/search/Showtek+Feat.+We+Are+Loud+%26+Sonny+Wilson+-+Booyah+(Original+Mix) http://site.com

    Дело в том что .htaccess файл есть и на главном сайте http://site.com и на поддомене http://music.site.com

    В принципе пойдет любой код любая манипуляция с любыми файлами главное что бы на эту страницу невозможно было попасть закрыть доступ к этой странице

    http://http://music.site.com/search/Showtek+Feat.+We+Are+Loud+%26+Sonny+Wilson+-+Booyah+(Original+Mix)

    Не пренципиально делать редирект или применять .htaccess файл главное закрыть доступ к этой странице

    Возможно есть еще другие способы исключить закрыть доступ к этой странице еще какимнеть другим методом не применяя файл .htaccess помогите нужно срочно закрыть доступ к этой странице

    Заранее благодарю

    Добавлено через 8 минут
    P.S Пробовал так
    RewriteRule ^music/search/Showtek+Feat.+We+Are+Loud+%26+Sonny+Wilson+-+Booyah+(Original+Mix)$ http://site.com/ [R=301,L]

    И так

    RewriteRule ^music.site.com/search/Showtek+Feat.+We+Are+Loud+%26+Sonny+Wilson+-+Booyah+(Original+Mix)$ http://site.com/ [R=301,L]

    Так

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteCond %{QUERY_STRING} ^(.*)$ [NC]
    RewriteRule ^music.site.com/search/Showtek+Feat.+We+Are+Loud+%26+Sonny+Wilson+-+Booyah+(Original+Mix)?$ /404.shtml [R=301,L]

    Не получилось не отдает 301 код

    Руками удалить невозможно так как эту страницу генерирует скрипт

    • Миша11 декабря 2013 в 10:12 #

      сорри, что не сразу ответил,
      а как насчет такого?

      global $user_ID;
      if( !$user_ID )
      	header("Location:" . site_url());
      • Liza12 декабря 2013 в 00:12 #

        Мне нужно было закрыть к определенную страницу, удалить ее невозможно как скрипт автоматом генерирует страницу
        Вообщем справилась сделала редирект на главную, а не получалось потому что в адресе был пробел а я его не заметила, сейчас все нормально
        Спасибо вам

  • Анна19 октября 2014 в 02:10 #

    А как убрать черную панель сверху, которая высвечивается при авторизации пользователя (она как раз ведет в административную панель)?
    Убрать нужно только для пользователей, админам надо оставить.

    • Миша19 октября 2014 в 08:10 #

      Попробуйте это:

      if( !current_user_can('administrator') ) {
      	add_filter('show_admin_bar', '__return_false');
      }

      Добавлять в файл functions.php.

      • Анна22 октября 2014 в 11:10 #

        Спасибо.
        Я так закрыла всё

        <?php
        /**
         * закрываем доступ в админку и админ-бар
         */
        function wp_admin_block() {
        if (!current_user_can('administrator') ) {
        status_header(404);
        nocache_headers();
        include( get_404_template() );
        exit;
        }
        }
        add_action('admin_menu', 'wp_admin_block');
         
        function hide_admin_bar_settings() {
        ?>
         
                  .show-admin-bar {
                       display: none;
                  }
         
        <?php
        }
         
        function disable_admin_bar() {
           if ( !current_user_can("administrator") ) {
              add_filter( 'show_admin_bar', '__return_false' );
              add_action( 'admin_print_scripts-profile.php',
                  'hide_admin_bar_settings' );
           }
        }
        add_action( 'init', 'disable_admin_bar' , 9 );
  • Матвей22 октября 2014 в 11:10 #

    Добрый день!
    Необходимо было реализовать на сайте электронную очередь. Сделал с помощью плагина Appointments Lite. Все заработало, но появилась загвоздка. Человек, к которому идет запись может увидеть полный список записавшихся только через консоль WP и показывается вся информация по этому плагину только из под Админа. Делать ее админом сайта не захотелось. Попытался с помощью различных других плагинов присвоить ей сначала другую роль, а потом надеялся установить права для новой роли. Так вот ни один плагин в упор не видит Appointments Lite, те можно установить любые права, кроме прав имеющих отношение к плагину. Думаю, ну, хорошо, может сделать ее админом, а через скрипт, подобный Вашему, но уже по ID пользователя сделать запреты на все кроме плагина... Но на этом работа встала, ничего дельного, кроме Вашего скрипта не нашел, а в Вашем не знаю как сделать запрет по ID.

    • Миша22 октября 2014 в 14:10 #

      Добрый день!
      Нужно немного доработать последнее условие:

      if( get_current_user_id() == тут указываете ID пользователя без кавычек){
      	add_action('admin_init', 'true_block_admin_pages_redirect');
      }

      Ещё можно так попробовать:

      global $user_ID;
      if($user_ID == тут указываете ID пользователя без кавычек){
      	add_action('admin_init', 'true_block_admin_pages_redirect');
      }
  • Матвей22 октября 2014 в 15:10 #

    Благодаря Вам я в очередной раз убедился как я далек от PHP;) Михаил, очень прошу Вас соединить вместе основной скрипт и условие, а то сижу и как банан на них смотрю. ID пользователя, которому хочу все запретить - 42. Пользователь будет Админом сайта, но у него нижеперчисленные пункты админского меню должны бить закрыты:
    /wp-admin/index.php
    /wp-admin/admin.php?page=all-in-one-seo-pack/aioseop_class.php
    /wp-admin/upload.php
    /wp-admin/edit.php?post_type=page
    /wp-admin/edit-comments.php
    /wp-admin/admin.php?page=wpcf7
    /wp-admin/edit.php?post_type=topic
    /wp-admin/edit.php?post_type=reply
    /wp-admin/plugins.php
    /wp-admin/users.php
    /wp-admin/tools.php
    /wp-admin/options-general.php
    /admin.php?page=shortcodes-ultimate
    /wp-admin/admin.php?page=nextgen-gallery
    /wp-admin/admin.php?page=wp-polls/polls-manager.php

    Доступ должен быть только сюда:
    /wp-admin/admin.php?page=appointments
    /wp-admin/admin.php?page=app_settings

    Михаил, буду Вам очень признателен. Могу сделать маленькую ссылку на Ваш ресурс под клиентским выводом плагина.

  • Матвей27 октября 2014 в 09:10 #

    Программист Игорь Пырко вот, что мне присоветовал на основе материалов Вашей статьи и комментов:

    function block_admin_pages_redirect() {
            global $pagenow;
            global $user_ID;
     
            $RESTRICTED_USER_ID = 42;
     
            if($user_ID == $RESTRICTED_USER_ID) {
                    if($pagenow != "index.php") {
                            $pages_to_pass = array(
                                    'admin.php'
                            );
                            $items_to_pass = array(
                                    'appointments',
                                    'app_settings'
                            );
     
                            $block = false;
                            if(in_array($pagenow, $pages_to_pass)){
                                    $selected_item = $_GET["page"];
                                    if(!in_array($selected_item, $items_to_pass)) {
                                            $block = true;
                                    }
                            } else {
                                    $block = true;
                            }
     
                            if($block) {
                                    wp_die('Вам не разрешен доступ к данной странице. <a href="' .admin_url('/'). '">Вернуться в админку.</a>');
                                    exit;
                            }
                    }
            }
    }
     
    if(current_user_can('administrator')){
            add_action('admin_init', 'block_admin_pages_redirect');
    }

    Для пользователя с админскими правами и с ID=42 разрешено только то, что прописано

  • Михаил Ж14 февраля 2015 в 21:02 #

    А как закрыть доступ к странице, которая не заканчивается на .php , например "/admin.php?page=storefront-welcome"?

Оставить комментарий / вопрос

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
Получайте новости блога по email или следите за мной в социальных сетях.
  • alex morozov: Ура, спасибо! Все-таки я разобрался ! Сделал:

  • alex morozov: Сделал Класс добаляется даже если поле пустое

  • Vladislav: Лучше бы посоветовали изящное решение имеющейся проблемы.

  • alex morozov: Не очень понял. Я добавляю метабокс через класс, почти как у вас. class Desc_Meta_Box { private $screens = array(...

  • Миша: Метод тыка хорош, но оснвоы нужно знать в любом случае. Рекомендую почитать это.