博客 / WordPress/ WordPress 定时清理从未登录的恶意注册用户(附完整代码)

WordPress 定时清理从未登录的恶意注册用户(附完整代码)

WordPress 定时清理从未登录的恶意注册用户(附完整代码)

许多 WordPress 站长都曾遭遇恶意注册用户的困扰。例如,曾有站点被恶意注册超过 70 万用户,导致数据库短时间内膨胀了 1GB 以上,严重影响网站性能和安全。

为了解决这个问题,我们可以通过 WordPress 的定时任务功能,自动清理那些从未登录过的恶意注册用户。本文将提供一个完整、安全的实现方案。

实现原理

本方案的核心是创建一个自定义的 WordPress 定时任务(Cron Job)。该任务会定期执行,查询并删除那些符合特定条件的用户(例如,注册后从未登录过的用户)。

完整实现代码

将以下代码添加到您当前主题的 functions.php 文件末尾,或通过代码片段插件(如 Code Snippets)添加。

/**
 * 1. 添加自定义的 Cron 时间间隔(例如:每10分钟)
 */
add_filter( 'cron_schedules', 'wp_cleanup_add_cron_interval' );
function wp_cleanup_add_cron_interval( $schedules ) {
    $schedules['every_ten_minutes'] = array(
        'interval' => 600, // 600秒 = 10分钟
        'display'  => __( '每隔10分钟', 'your-text-domain' )
    );
    return $schedules;
}

/**
 * 2. 调度定时任务(如果尚未调度)
 */
if ( ! wp_next_scheduled( 'wp_cleanup_inactive_users_hook' ) ) {
    wp_schedule_event( time(), 'every_ten_minutes', 'wp_cleanup_inactive_users_hook' );
}

/**
 * 3. 定义定时任务要执行的操作:清理用户
 */
add_action( 'wp_cleanup_inactive_users_hook', 'wp_cleanup_inactive_users' );
function wp_cleanup_inactive_users() {
    // 获取所有用户
    $all_users = get_users( array( 'fields' => array( 'ID', 'user_registered' ) ) );

    foreach ( $all_users as $user ) {
        $user_id = $user->ID;

        // 关键判断:检查用户是否从未登录过。
        // 方法:检查用户元数据 `last_login` 是否存在或为空。
        // 注意:WordPress 默认不记录最后登录时间,需要插件或额外代码支持。
        // 这里提供一个更通用的替代方案:检查用户注册时间与当前时间差,并确保用户角色为“订阅者”等低级角色。
        $user_data = get_userdata( $user_id );
        $user_roles = $user_data->roles;

        // 示例条件:删除注册超过7天且从未发表过文章、评论的“订阅者”角色用户
        // 这是一个更安全的策略,避免误删活跃用户。
        $days_old = 7;
        $registered_time = strtotime( $user->user_registered );
        $cutoff_time = strtotime( "-$days_old days" );

        // 检查用户是否有文章或评论
        $post_count = count_user_posts( $user_id );
        $comment_count = get_comments( array( 'user_id' => $user_id, 'count' => true ) );

        if ( in_array( 'subscriber', $user_roles ) && // 角色为订阅者
             $registered_time < $cutoff_time && // 注册超过设定天数
             $post_count == 0 && // 从未发表文章
             $comment_count == 0 // 从未发表评论
        ) {
            // 执行删除
            // 注意:如果用户有文章,需要指定文章继承者,否则文章会被删除。
            // 由于我们已确保 $post_count == 0,这里可以直接删除。
            require_once( ABSPATH . 'wp-admin/includes/user.php' );
            wp_delete_user( $user_id );
        }
    }
}

/**
 * 4. (可选) 插件停用时清理定时任务
 */
register_deactivation_hook( __FILE__, 'wp_cleanup_deactivation' );
function wp_cleanup_deactivation() {
    $timestamp = wp_next_scheduled( 'wp_cleanup_inactive_users_hook' );
    if ( $timestamp ) {
        wp_unschedule_event( $timestamp, 'wp_cleanup_inactive_users_hook' );
    }
}

代码说明与安全建议

1. 自定义时间间隔

通过 cron_schedules 过滤器添加了一个名为 every_ten_minutes 的间隔(10分钟)。您可以根据需要修改 interval 的值(单位:秒),例如改为每小时(3600秒)或每天(86400秒)。

2. 核心清理逻辑(重要)

原示例代码通过一个自定义字段(jh)判断用户,这并不通用。上述重写后的代码采用了更稳健的策略:

  • 目标用户:角色为“订阅者”(Subscriber)。
  • 注册时间:超过设定的天数(示例为7天)。
  • 活跃度检查:确保该用户从未发表过文章或评论。

这三个条件叠加,可以极大程度地避免误删正常用户,精准打击“注册后即沉寂”的恶意用户。

3. 关于用户删除

wp_delete_user() 函数在删除拥有文章的用户时,必须指定一个文章继承者($reassign 参数),否则该用户的所有文章将被一并删除。在我们的逻辑中,由于已确保用户无文章($post_count == 0),所以可以安全地直接删除。

4. 管理定时任务

  • 查看任务:可以安装 “WP Crontrol” 或 “Advanced Cron Manager” 等插件来查看和管理您的自定义定时任务。
  • 停止清理:如果您想停止自动清理,只需从 functions.php 中移除上述代码,或通过代码片段插件停用该片段即可。代码中已包含停用钩子作为示例。

扩展:记录用户最后登录时间

要实现更精确的“从未登录”判断,需要记录用户的最后登录时间。您可以在主题的 functions.php 中添加以下代码:

// 记录用户登录时间
add_action( 'wp_login', 'wp_record_user_last_login', 10, 2 );
function wp_record_user_last_login( $user_login, $user ) {
    update_user_meta( $user->ID, 'last_login', current_time( 'mysql' ) );
}

添加此代码后,您可以将主清理函数中的判断条件改为检查 last_login 元数据是否存在。如果不存在,则说明该用户自您添加此代码后从未登录过。

通过以上方案,您可以有效自动化 WordPress 站点的用户清理工作,保持数据库的整洁与高效运行。

发表评论

您的邮箱不会公开。必填项已用 * 标注。