web-dev-qa-db-ja.com

ユーザーを禁止してセッションを終了する

私はこれから派生したプラグインに取り組んでいます tutorial 。これまでのところ、プラグインはユーザーのプロファイル編集ページにチェックボックスを追加し、管理者はユーザーを禁止できます。

checkbox

チェックした場合、ユーザーはログイン時にメッセージを受け取ります。

banned

正常に動作します。問題は、ユーザーが既にログインしている(アクティブなセッションを持っている)ために禁止された場合、ユーザーはサイトuntilとの対話を続行できることです。セッションが終了するか、ユーザーがログアウトします。

ユーザーを強制的に追い出すために、禁止時にユーザーのセッションを終了するにはどうすればよいですか?

コードは次のとおりです。

/**
 * 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()関数に進む必要があります。

編集:完全なプラグインが投稿されました

6

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;
}
5
fuxia

Toschoのメソッドは機能しますが、より直接的な方法では、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;
}

認証フィルターチェーンを使用すると、ユーザーが認証を受ける可能性があるたびにユーザーを認証するかどうかを決定できます。値を返すとWP_Userがログインします。何らかの方法でWP_Errorを返すと、ユーザー名/パスワードを介したものであれCookieを介したものであれ、認証の試行に失敗します。

4
Otto

私も同様のプラグインを書き、すでにWordPress.orgに公開しています。私は最善の解決策はすぐに管理者が "禁止"(ブロック)ボタン(リンク)をクリックしてユーザーセッションをドロップすると思います。これはWP_Session_Tokensクラスで可能です:

$manager = \WP_Session_Tokens::get_instance( $user_id );
$manager->destroy_all();

また、現在ユーザーが認証されていて/wp-admin/の一部のページが開かれている場合でも、既に(すぐに)セッションを削除しているため、強制的にログアウトされます。

ソースコード: https://wordpress.org/plugins/mark-user-as-spammer/ /

2

プラグインを使用する準備が整い、エレガントに機能します。元のチュートリアルの Remi 、および禁止時のエンドユーザーセッションへの実用的な解決策の toscho (ボット)に感謝します。

今後のアップデート

私は将来のアップデートのために以下を計画します:

  • 禁止時にユーザーのコメントや投稿を削除するオプション。
  • 特定のユーザーにカスタム禁止メッセージを追加します。
  • 管理者がwp-adminのユーザー一覧ページで複数のユーザーを禁止することを許可します。

更新提案がある場合はコメントを残してください。プラグインに更新があるたびに、私はこの答えを編集します。

ユーザー禁止プラグイン

プラグインフォルダに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 );
1