禁止用户并结束其会话

时间:2013-11-20 作者:Christine Cooper

我正在开发一个源于此的插件tutorial. 到目前为止,该插件在用户的个人资料编辑页面上添加了一个复选框,管理员可以在其中禁止该用户。

checkbox

如果选中,用户将在登录时收到一条消息:

banned

它工作得很好。问题是,如果用户已经登录(有一个活动会话)并且被禁止,那么用户可以继续与该站点交互until 会话结束或用户注销。

How do I end the user\'s session upon banning so the user is forced out?

代码如下:

/**
 * Admin init
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_admin_init(){

    // Edit user profile
    add_action( \'edit_user_profile\', \'rc_edit_user_profile\' );
    add_action( \'edit_user_profile_update\', \'rc_edit_user_profile_update\' );

}
add_action(\'admin_init\', \'rc_admin_init\' );


/**
 * Adds custom checkbox to user edition page
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_edit_user_profile() {
    if ( !current_user_can( \'edit_users\' ) ) {
        return;
    }

    global $user_id;

    // User cannot disable itself
    $current_user = wp_get_current_user();
    $current_user_id = $current_user->ID;
    if ( $current_user_id == $user_id ) {
        return;
    }
    ?>
    <h3>Ban user</h3>
    <table class="form-table">
    <tr>
        <th scope="row"></th>
        <td><label for="rc_ban"><input name="rc_ban" type="checkbox" id="rc_ban"  /> Check to ban user.</label></td>
    </tr>
    </table>
    <?php
}


/**
 * Save custom checkbox
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_edit_user_profile_update() {

    if ( !current_user_can( \'edit_users\' ) ) {
        return;
    }

    global $user_id;

    // User cannot disable itself
    $current_user    = wp_get_current_user();
    $current_user_id = $current_user->ID;
    if ( $current_user_id == $user_id ) {
        return;
    }

    // Lock
    if( isset( $_POST[\'rc_ban\'] ) && $_POST[\'rc_ban\'] = \'on\' ) {
        rc_ban_user( $user_id );
    } else { // Unlock
        rc_unban_user( $user_id );
    }

}


/**
 * Ban user
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_ban_user( $user_id ) {

    $old_status = rc_is_user_banned( $user_id );

    // Update status
    if ( !$old_status ) {
        update_user_option( $user_id, \'rc_banned\', true, false );
    }
}


/**
 * Un-ban user
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_unban_user( $user_id ) {

    $old_status = rc_is_user_banned( $user_id );

    // Update status
    if ( $old_status ) {
        update_user_option( $user_id, \'rc_banned\', false, false );
    }
}


/**
 * Checks if a user is already banned
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_is_user_banned( $user_id ) {
    return get_user_option( \'rc_banned\', $user_id, false );
}


/**
 * Check if user is locked while login process
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_authenticate_user( $user ) {

    if ( is_wp_error( $user ) ) {
        return $user;
    }

    // Return error if user account is banned
    $banned = get_user_option( \'rc_banned\', $user->ID, false );
    if ( $banned ) {
        return new WP_Error( \'rc_banned\', __(\'<strong>ERROR</strong>: This user account is disabled.\', \'rc\') );
    }

    return $user;
}

add_filter( \'wp_authenticate_user\', \'rc_authenticate_user\', 1 );
因此,会话的结束应该在rc_ban_user() 作用

EDIT: 已发布完整插件below.

4 个回复
最合适的回答,由SO网友:fuxia 整理而成

使用wp_logout(). 它调用wp_clear_auth_cookie() 并立即使当前登录信息无效。

未测试的示例代码:

add_action( \'init\', \'log_out_banned_user\' );

function log_out_banned_user() {
    if ( ! is_user_logged_in() )
        return;

    $user = wp_get_current_user();

    if ( ! get_user_option( \'rc_banned\', $user->ID, false ) )
        return;

    wp_logout();
    wp_redirect( home_url( \'/\' ) );
    exit;
}

SO网友:Otto

虽然托肖的方法可行,但更简单的方法可能是使用authenticate 钩子以更直接的方式阻止他们通过cookie或任何其他方式进行身份验证。

完全未经测试的代码。不过应该可以。

// the priority of 999 is to ensure it\'s last in the auth chain
add_filter(\'authenticate\', \'force_fail_banned_users\', 999, 3); 

function force_fail_banned_users($user, $username, $password) {
    if ( ! is_a($user, \'WP_User\') ) { 
        // we only care about actual users who already auth\'d okay via some means
        return $user; 
    }

    if ( rc_is_user_banned( $user->ID ) ) {
        // user is banned, so return a failure case
        return new WP_Error(\'banned_user\', \'Banned message goes here.\');
    }

    // user not banned, so return the user normally
    return $user;
}
authenticate筛选器链允许您决定是否在每个可能的机会对用户进行身份验证。返回值WP\\u用户将其登录。返回任何类型的WP\\U错误都会使他们的身份验证尝试失败,无论是通过用户名/密码还是通过cookie进行验证。

SO网友:Kolya Korobochkin

我还编写了类似的插件,并已将其发布在WordPress上。组织。我认为最好的解决方案是立即删除用户会话,然后管理员单击“禁止”(阻止)按钮(链接)。这可能与WP_Session_Tokens 类别:

$manager = \\WP_Session_Tokens::get_instance( $user_id );
$manager->destroy_all();
即使用户当前已授权并且/wp-admin/ 打开后,将强制注销,因为我们已经(立即)删除了会话。

源代码:https://wordpress.org/plugins/mark-user-as-spammer/

SO网友:Christine Cooper

该插件现在可以使用了,功能也很好。幸亏Remi 对于原始教程和toscho (bot)为最终用户会话提供工作解决方案。

未来更新

我计划未来更新如下:

禁止时删除用户评论或/和帖子的选项

禁止用户插件创建一个名为ban-users 在插件文件夹中创建一个名为ban-users.php 使用以下代码:

<?php
/*
Plugin Name: Ban Users
Plugin URI: http://wordpress.stackexchange.com/questions/123902/ban-a-user-and-end-their-session
Description: Allows you to ban users
Author: Christine Cooper, Remi, toscho
Version: 1.1
Author URI: http://wordpress.stackexchange.com/questions/123902/ban-a-user-and-end-their-session
*/


/**
 * Admin init
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_admin_init(){

    // Edit user profile
    add_action( \'edit_user_profile\', \'rc_edit_user_profile\' );
    add_action( \'edit_user_profile_update\', \'rc_edit_user_profile_update\' );

}
add_action(\'admin_init\', \'rc_admin_init\' );


/**
 * Adds custom checkbox to user edition page
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_edit_user_profile() {
    if ( !current_user_can( \'edit_users\' ) ) {
        return;
    }

    global $user_id;

    // User cannot disable itself
    $current_user = wp_get_current_user();
    $current_user_id = $current_user->ID;
    if ( $current_user_id == $user_id ) {
        return;
    }
    ?>
    <h3>Ban User</h3>
    <table class="form-table">
    <tr>
        <th scope="row"></th>
        <td><label for="rc_ban"><input name="rc_ban" type="checkbox" id="rc_ban" <?php if ( get_user_option( \'rc_banned\', $user_id, false ) ) { echo \'checked\'; } ?> /> Check to ban user </label></td>
    </tr>
    </table>
    <?php
}


/**
 * Save custom checkbox
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_edit_user_profile_update() {

    if ( !current_user_can( \'edit_users\' ) ) {
        return;
    }

    global $user_id;

    // User cannot disable itself
    $current_user    = wp_get_current_user();
    $current_user_id = $current_user->ID;
    if ( $current_user_id == $user_id ) {
        return;
    }

    // Lock
    if( isset( $_POST[\'rc_ban\'] ) && $_POST[\'rc_ban\'] = \'on\' ) {
        rc_ban_user( $user_id );
    } else { // Unlock
        rc_unban_user( $user_id );
    }

}


/**
 * Ban user
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_ban_user( $user_id ) {

    $old_status = rc_is_user_banned( $user_id );

    // Update status
    if ( !$old_status ) {
        update_user_option( $user_id, \'rc_banned\', true, false );
    }
}


/**
 * Un-ban user
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_unban_user( $user_id ) {

    $old_status = rc_is_user_banned( $user_id );

    // Update status
    if ( $old_status ) {
        update_user_option( $user_id, \'rc_banned\', false, false );
    }
}


/**
 * Checks if a user is already banned
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_is_user_banned( $user_id ) {
    return get_user_option( \'rc_banned\', $user_id, false );
}



/**
 * End a users active session if they are banned
 * By toscho http://wordpress.stackexchange.com/a/123903/24875
 *
 * @access      public
 * @since       1.1 
 * @return      void
*/
add_action( \'init\', \'log_out_banned_user\' );

function log_out_banned_user() {
    if ( ! is_user_logged_in() )
        return;

    $user = wp_get_current_user();

    if ( ! get_user_option( \'rc_banned\', $user->ID, false ) )
        return;

    wp_logout();
    wp_redirect( home_url( \'/\' ) );
    exit;
}



/**
 * Check if user is locked while login process
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_authenticate_user( $user ) {

    if ( is_wp_error( $user ) ) {
        return $user;
    }

    // Return error if user account is banned
    $banned = get_user_option( \'rc_banned\', $user->ID, false );
    if ( $banned ) {
        return new WP_Error( \'rc_banned\', __(\'<strong>ERROR</strong>: Your user account has been disabled.\', \'rc\') );
    }

    return $user;
}

add_filter( \'wp_authenticate_user\', \'rc_authenticate_user\', 1 );

结束

相关推荐

Paginate a list of users?

我目前正在使用以下代码显示所有用户的列表。唯一的问题是我需要分页,一次只显示10个用户。我熟悉使用CPT和POST的分页,但不熟悉用户。这可能吗?如果是,我从哪里开始? <?php /** * @package WordPress * @subpackage themename * Template Name: Vendors Page */ get_header(); ?> <?php $