仅允许特定用户角色登录WordPress站点

时间:2017-05-04 07:49:18

标签: php wordpress redirect restrict

我目前有一个WP网站设置,其中安装了一个独特的“多站点”插件,专门用于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并添加注释“您必须是交易客户......等”。但是,在首次登录任何用户角色后,每次其他登录尝试都会执行相同的重定向并显示消息。我的代码是不正确的还是数据库或浏览器中有一些WP会话cookie导致WP认为我没有使用管理员帐户的问题?

我第一次尝试登录是使用管理员帐户。它工作,并去仪表板。下一次尝试是使用客户角色帐户。发生了重定向和注释。以下使用管理员帐户的尝试仅使用note进行重定向,但没有使用仪表板访问。

3 个答案:

答案 0 :(得分:1)

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 :(得分:0)

我的新完整代码现在是:

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');

此代码正常运行。然而,正如Kulivov Sergey在回复中提到的,使用身份验证过滤器而不是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);

不仅在没有登录和创建会话的情况下检查用户角色,它还使用户保持在当前页面上而没有重定向,这很棒。

答案 2 :(得分:0)

我已经测试了以下代码是否可以正常工作。

无需运行wp_destroy_current_session()wp_logout(),只需返回一个错误即可,它会中断身份验证并在登录页面上显示您的错误消息。

您可能必须确保优先级为最后(在这种情况下为100),以便现有过滤器wp_authenticate_username_passwordwp_authenticate_email_passwordwp_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;       
    }
}