Как настроить авторизацию/логин для просмотра определенного набора записей/страниц?
Я работаю над WordPress сайтом для клиента, которому нужен внутренний 'интранет' для его сотрудников. Основные потребности:
- Внутренняя коммуникация
- Хранение важных корпоративных документов
- Предоставление быстрого доступа к ресурсам для сотрудников.
Эта информация является конфиденциальной и предназначена только для сотрудников. Они хотели бы, чтобы у каждого сотрудника был свой логин/пароль, и доступ к информации и документам был возможен только после авторизации.
Я видел эти плагины и несколько похожих, но они кажутся ограниченными, и конечно, они уже полностью устарели:
- http://wordpress.org/extend/plugins/wp-require-auth/
- http://wordpress.org/extend/plugins/members-only/
Я знаю, что могу защитить паролем отдельные записи/страницы. Могу ли я защитить паролем целую категорию записей или, что еще лучше, пользовательский тип записей? По сути, мне нужно сгруппировать некоторые страницы/записи под одной авторизацией. Информация конфиденциальна, поэтому она не должна быть доступна, например, в RSS-ленте. Как я могу это сделать?
- Вариант 1 (менее желательный): весь WordPress сайт за стеной авторизации
- Вариант 2 (более желательный): только внутренние страницы/записи за стеной авторизации
Итог: я готов рассмотреть вариант 1, если он НАМНОГО проще, но предпочел бы вариант 2. На данный момент, после некоторого исследования, я нахожу только устаревшие плагины, которые помогают с этим, и не могу найти надежный способ реализовать ни один из вариантов. Спасибо за помощь!

Это просто модификация ответа timshutes - если вам нужно, чтобы определенные страницы требовали входа в систему, и вы не хотите помещать их в пользовательский тип записи, вы можете добавить в functions.php:
add_shortcode('need_login', 'shortcode_needLogin');
function shortcode_needLogin() {
if (!is_user_logged_in()) {
auth_redirect();
}
}
Затем в начале страниц, для которых требуется вход в систему, вы можете просто добавить:
[need_login]

Можно добавить проверку на соответствующих архивных страницах и одиночных страницах.
Но одна вещь, которую вам точно стоит сделать вместе с другими решениями — это использовать фильтр the_posts
. Он фильтрует записи, которые получает любой WP_Query. Вы получите массив объектов записей. Проверьте условие и удалите объект, если он там есть. Это решение предназначено для случаев, когда все другие способы обходятся. Это последний рубеж, если какой-то неизвестный плагин получает записи без вашего ведома.
Ещё один фильтр, который стоит использовать — pre_get_posts
, чтобы проверять переменные запроса и изменять их по необходимости.
Также есть фильтр posts_where
— используйте его, чтобы добавить дополнительное условие WHERE в MySQL-запрос.
Это не полностью безопасно, но должно покрыть большинство случаев, включая внешние плагины.
Если вы используете пользовательский тип записи (custom post type), всё становится намного проще. Вы можете задать специальные права для этого типа записи и предоставить их только пользователям с определённой ролью.
Вы можете попросить клиента вручную устанавливать каждую запись как приватную, но будьте уверены — они будут забывать это делать время от времени. Если безопасность важна, лучше не выбирать этот путь.

Это устарело, но вот как я в итоге решил эту проблему.
- Создал пользовательский тип записи для страниц интранета.
- Добавил функцию "force_login" в functions.php
- Включил функцию принудительной авторизации в начале всех необходимых файлов шаблонов страниц.
Вы можете настроить это для разрешения доступа только определенным пользователям — например, используя плагин "Members", который упомянул @jason.
Код:
В functions.php
/* Требовать авторизацию для интранета */
function my_force_login() {
global $post;
if (!is_user_logged_in()) {
auth_redirect();
}
}
В начале файлов page-intranet.php и single-intranet-pages.php
<?php my_force_login(); ?>
И... всё. Это работает.
Примечания по безопасности:
- Я не знаю точно почему, но мне кажется, что безопасность этого метода не абсолютна.
- Это работает в моей ситуации, но если вам нужна абсолютная защита, изучите вопрос глубже.
- Смотрите ответ @Mridul ниже для дополнительной информации
Если у вас есть простой и более безопасный метод для этого, оставьте его в комментариях, и я отмечу его как правильный ответ.

Вы можете установить видимость содержимого как приватную для определенных страниц, что потребует от посетителей наличия входа в WordPress И определенного уровня прав для просмотра содержимого. Возможно, я бы предложил создать шаблон template-intranet.php
для страницы "Интранет" и добавить пользовательское меню для страниц, которые являются частью интранета, чтобы их можно было перечислить на этой странице. Вам все равно придется установить статус всех страниц как "Приватные".
Обходной путь для установки всех страниц интранета как приватных — в файле functions.php
вы можете написать условную проверку, является ли текущая страница дочерней по отношению к странице "Интранет" — если страница является дочерней, проверить, авторизован ли пользователь, и если нет, перенаправить его, в противном случае продолжить загрузку страницы.

Если вы хотите вручную управлять аутентификацией и интегрировать её в систему аутентификации WordPress, то у @Rezen правильный подход. Однако я бы предпочёл использовать определённый шаблон страницы или список шаблонов страниц для проверки аутентификации.
Также вы можете посмотреть плагин "Members" от Justin Tadlock - он предоставляет множество возможностей для управления пользовательскими ролями, которые вы могли бы использовать.

Фильтры:
add_filter('template_include', 'theme_check_user_permissions', 1, 1);
add_filter('logout_url','theme_logout_redirect');
if(!current_user_can('edit_users')) add_filter( 'wp_die_handler', create_function('',"return 'theme_wp_die_handler';"));
Если пользователь не зарегистрирован, перенаправляем на страницу входа (guest.php, без панели управления)
function theme_check_user_permissions($template)
{
return (is_user_logged_in() ? $template : TEMPLATEPATH.'/guest.php');
}
После входа перенаправляем на главную страницу
function theme_logout_redirect($url, $redirect = null)
{
return $url.'&redirect_to='.urlencode(get_bloginfo('url'));
}
Удаляем стандартную страницу wp_die (перенаправляем на главную)
function theme_wp_die_handler()
{
wp_redirect(get_bloginfo('url'),307);
exit;
}
