Разрешить входить на сайт WordPress только определенным пользовательским ролям

В настоящее время у меня есть настройка сайта WP с уникальным плагином ‘multisite’, установленным специально для разрешения одной области администрирования продуктов WooCommerce, но с 2 разными интерфейсами на основе 2 разных доменов с отдельными темами.

Один из этих сайтов является «оптовым», а другой — «розничным». Оптовый сайт должен позволять торговым клиентам совершать покупки. Проблема заключается в том, что оба сайта совместно используют один домен и, следовательно, учетные записи пользователей.

Проблема: мне нужно убедиться, что пользователь, у которого нет роли «trade_customer», пытается войти на оптовый сайт, роль проверяется, и пользователь выходит из системы, перенаправляется на страницу входа с уведомлением. Пока что у меня есть следующее в functions.php:

function trade_customers_only() {
function get_user_role() {
global $current_user;

$user_roles = $current_user->roles;
$user_role = array_shift($user_roles);

return $user_role;
}

$the_current_role = get_user_role();
echo $the_current_role;
if( $the_current_role != 'administrator' ) {
$logout_url = wp_login_url().'?mode=tradeonly';
wp_destroy_current_session();
wp_logout();
wp_redirect( $logout_url, 302 );
exit();
}
}
add_action('wp_login', 'trade_customers_only');

// CUSTOM LOGIN MESSAGES
function my_login_message() {

if( $_GET['mode'] == 'tradeonly' ){
$message = '<p class="message"><b>You must be a Trade Customer to access this site.</b></p>';
return $message;
}

}
add_filter('login_message', 'my_login_message');

Этот код в настоящее время: возвращает зарегистрированного пользователя в wp-login.php и добавляет примечание «Вы должны быть торговым клиентом … и т. Д.». Тем не менее, после первой попытки входа в систему с любой ролью пользователя, каждая вторая попытка входа в систему делает то же самое перенаправление и показывает сообщение. Мой код неверен или в БД или браузере есть какой-то файл cookie сеанса WP, вызывающий проблему, из-за которой WP считает, что я не использую учетную запись администратора?

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

0

Решение

1) Измени свой trade_customers_only функция:

function trade_customers_only($login, $user) {
if( $user->roles && !in_array('administrator',$user->roles)) {
$logout_url = wp_login_url().'?mode=tradeonly';
wp_destroy_current_session();
wp_logout();
wp_redirect( $logout_url, 302 );
exit();
}
}

И исправьте свой призыв к действию:

add_action('wp_login', 'trade_customers_only',10,2);

2) Другое решение использует проверять подлинность фильтр вместо использования wp_login действие. Разница в том, что вы проверяете роль пользователя до того, как пользователь установит сеанс, поэтому вам не нужно ее уничтожать.

add_filter('authenticate',function($user,$username) {
if (!is_wp_error($user)) {
$auth_user=get_user_by('login',$username);
if ($auth_user && !in_array('administrator',$auth_user->roles)) {
return new WP_Error('authentication_failed', '<p class="message"><b>You must be a Trade Customer to access Key Essentials. Are you looking for <a href="https://lovetillys.co.uk" title="Love Tillys">Love Tillys?</a></b></p>');
}
}
return $user;
},100,2);
1

Другие решения

Мой новый полный код сейчас:

function trade_customers_only($login, $user) {
if( $user->roles && !in_array('administrator',$user->roles)) {
$logout_url = wp_login_url().'?mode=tradeonly';
wp_destroy_current_session();
wp_logout();
wp_redirect( $logout_url, 302 );
exit();
}
}
add_action('wp_login', 'trade_customers_only',10,2);

// CUSTOM LOGIN MESSAGES
function my_login_message() {

if( $_GET['mode'] == 'tradeonly' ){
$message = '<p class="message"><b>You must be a Trade Customer to access this site.</b></p>';
return $message;
}

}
add_filter('login_message', 'my_login_message');

Этот код работает правильно. Однако, как отметил в своем ответе Куливов Сергей, используя аутентификацию фильтр вместо wp_login действие лучше для того, что мне нужно достичь. С помощью:

add_filter('authenticate',function($user,$username) {
if (!is_wp_error($user)) {
$auth_user=get_user_by('login',$username);
if ($auth_user && !in_array('administrator',$auth_user->roles)) {
return new WP_Error('authentication_failed', '<p class="message"><b>You must be a Trade Customer to access this site.</b></p>');
}
}
return $user;
},100,2);

Он не только проверяет роль пользователя без входа в систему и создания сеанса, но также сохраняет пользователя на его текущей странице без перенаправления, и это здорово.

0

Я проверил код ниже, как работает правильно.

Там нет необходимости бежать wp_destroy_current_session() или же wp_logout()просто вместо этого верните ошибку, и она прервет аутентификацию и покажет ваше сообщение об ошибке на странице входа.

Возможно, вам придется убедиться, что приоритет является последним (в данном случае 100), чтобы существующие фильтры wp_authenticate_username_password, wp_authenticate_email_password а также wp_authenticate_spam_check все делают свое дело, и до того, как пользователь полностью войдет в систему, вы потом откажетесь.

/* Only allow administrators to login */
add_filter( 'authenticate', 'my_admin_check', 100, 1 );

function my_admin_check( $user ) {
// Make sure this is a real login attempt, without errors
if ( !is_wp_error($user) ) {
$user_role = $user->roles[0];
// add or remove the roles you want to allow/disallow (can be a custom role or regular WordPress roles)
if ( !in_array( $user_role, array( 'trade_customer' ) ) ){
return new WP_Error( 'login_failed', __( "Only staff can use this login.", "mysite_domain" ) );
} else {
// allow the login
return $user;
}
} else {
// We're just loading the login page, not running a login.
return $user;
}
}
0
По вопросам рекламы [email protected]