admin管理员组

文章数量:1122846

I'd like to forcefully log users out when their role is changed. For example, if a user is logged into the site and has an existing role of 'Editor' and I change the role to 'No role for this site', the user should be logged out if they attempt to navigate anywhere on the site including the frontend and the WordPress dashboard.

The code I'm using below doesn't seem to work when roles are changed. It only works if a user isn't logged in and attempts to.

function logout_pending_users( $username, $user ) {
    
    if ( $user instanceof \WP_User && ! $user->has_cap( 'read' ) ) {

        wp_logout();
        session_unset();
        session_destroy(); 
        wp_destroy_current_session();
        wp_clear_auth_cookie();
        wp_set_current_user( 0 );
        
        $redirect_url = esc_url( home_url() );
        wp_safe_redirect( $redirect_url );
        exit;
    }
}
add_action( 'wp_login', 'logout_pending_users', 100, 2 );

What am I doing wrong?

Updated example

To illustrate the functionality not working as intended as per the comments with @mmm and the request to share an example, here's the sample code.

function logout_pending_users( $user_id, $new_role, $old_roles ) {
    global $wp_session;
    $user = get_userdata( $user_id );
    
    if ( ! $user->has_cap( 'read' ) || $new_role === '' ) {
        $session = wp_get_session_token();
        $sessions = WP_Session_Tokens::get_instance( $user->ID );
        $sessions->destroy_others( $session );
        
        $redirect_url = esc_url( home_url() );
        wp_safe_redirect( $redirect_url );
        exit;
    }
}
add_action( 'set_user_role', 'logout_pending_users', 10, 3 );

I'd like to forcefully log users out when their role is changed. For example, if a user is logged into the site and has an existing role of 'Editor' and I change the role to 'No role for this site', the user should be logged out if they attempt to navigate anywhere on the site including the frontend and the WordPress dashboard.

The code I'm using below doesn't seem to work when roles are changed. It only works if a user isn't logged in and attempts to.

function logout_pending_users( $username, $user ) {
    
    if ( $user instanceof \WP_User && ! $user->has_cap( 'read' ) ) {

        wp_logout();
        session_unset();
        session_destroy(); 
        wp_destroy_current_session();
        wp_clear_auth_cookie();
        wp_set_current_user( 0 );
        
        $redirect_url = esc_url( home_url() );
        wp_safe_redirect( $redirect_url );
        exit;
    }
}
add_action( 'wp_login', 'logout_pending_users', 100, 2 );

What am I doing wrong?

Updated example

To illustrate the functionality not working as intended as per the comments with @mmm and the request to share an example, here's the sample code.

function logout_pending_users( $user_id, $new_role, $old_roles ) {
    global $wp_session;
    $user = get_userdata( $user_id );
    
    if ( ! $user->has_cap( 'read' ) || $new_role === '' ) {
        $session = wp_get_session_token();
        $sessions = WP_Session_Tokens::get_instance( $user->ID );
        $sessions->destroy_others( $session );
        
        $redirect_url = esc_url( home_url() );
        wp_safe_redirect( $redirect_url );
        exit;
    }
}
add_action( 'set_user_role', 'logout_pending_users', 10, 3 );
Share Improve this question edited Sep 5, 2024 at 19:36 Ryan asked Sep 3, 2024 at 9:14 RyanRyan 631 silver badge7 bronze badges 5
  • you can use this to disconnect all sessions of a user : developer.wordpress.org/reference/classes/wp_session_tokens/… – mmm Commented Sep 3, 2024 at 10:39
  • Thanks @mmm. I did try it before posting the question here and it doesn't work either. It still keeps me logged in. – Ryan Commented Sep 3, 2024 at 19:39
  • I try the code with "set_user_role" and I found the problem. when the user is disconnected, wordpress doesn't longer know which was the user then it's complicated to do a redirection at this moment. I just realise that it's a little bit brutal to logout a user like that, why do you need to change role while a user is using the back office ? – mmm Commented Sep 6, 2024 at 0:21
  • There are plenty of reasons. For example, if a user has been terminated, there may be a need to ensure that they can no longer use the site. Another example is when a user's account has been compromised and you need to disable it immediately. – Ryan Commented Sep 9, 2024 at 5:44
  • there is no problem of changing the role of a user. my question is about the logout and redirection you want to add. at the second you set the new role, the user lost the capabilities of the old role, then you don't have to make something special even if he is still connected. – mmm Commented Sep 9, 2024 at 5:53
Add a comment  | 

1 Answer 1

Reset to default 0

The wp_login hook you are using only triggers when a user login, while we need to trigger function when user changed their role.

The correct for this will be set_user_role hook.

Please update your code with the given code so User will logout on changing the role.

function logout_pending_users( $user_id, $new_role, $old_roles ) {
    // Here we are getting the user object.
    $user = get_userdata( $user_id );

    // If the user no longer has the 'read' capability or if the new role is 'No role for this site'
    if ( ! $user->has_cap( 'read' ) || $new_role === '' ) {
        // Here we are logging the user out.
        wp_logout();

        // Here we are destroying the current session and clear cookies.
        wp_destroy_current_session();
        wp_clear_auth_cookie();
        wp_set_current_user( 0 );

        // Here we are redirecting the user to the homepage or any other URL as per our need.
        $redirect_url = esc_url( home_url() );
        wp_safe_redirect( $redirect_url );
        exit;
    }
}
add_action( 'set_user_role', 'logout_pending_users', 10, 3 );

本文标签: capabilitiesForce logout when role is changed