You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pluggable.php加载前验证wp_redirect环节的用户登录状态?

解决wp_redirect钩子中提前验证用户登录状态的问题

问题场景

想要通过site_url和wp_redirect钩子实现:未登录且访问非后台页面时,重定向到根目录。初始代码如下:

<?php

add_filter( 'site_url', 'my_prefix_site_url', 10, 2 );
add_filter( 'wp_redirect', 'my_prefix_wp_redirect' );

function my_prefix_site_url( $url, $scheme ) {
    return my_prefix_modify_url( $url, $scheme );
}

function my_prefix_wp_redirect( $url ) {
    return my_prefix_modify_url( $url, null );
}

function my_prefix_modify_url( $url, $scheme = null ) {
    $current_url = isset( $_SERVER['PHP_SELF'] ) ? sanitize_text_field( wp_unslash( $_SERVER['PHP_SELF'] ) ) : '';

    if ( ! strpos( $current_url, 'wp-admin' ) && ! is_user_logged_in() ) {
        return '/';
    }

    return $url;
}

运行时触发致命错误:

Fatal error: Uncaught Error: Call to undefined function is_user_logged_in()

排查发现wp_redirect钩子的触发时机早于is_user_logged_in()所在的pluggable.php文件加载。手动引入该文件虽能让代码运行,但会破坏其他插件对可插拔函数的覆盖机制,引发冲突。

解决方案:直接验证登录Cookie

绕过is_user_logged_in()函数,直接通过WordPress的登录Cookie验证用户状态,避免依赖未加载的文件。修改后的代码如下:

<?php

add_filter( 'site_url', 'my_prefix_site_url', 10, 2 );
add_filter( 'wp_redirect', 'my_prefix_wp_redirect' );

function my_prefix_site_url( $url, $scheme ) {
    return my_prefix_modify_url( $url, $scheme );
}

function my_prefix_wp_redirect( $url ) {
    return my_prefix_modify_url( $url, null );
}

function my_prefix_modify_url( $url, $scheme = null ) {
    $current_url = isset( $_SERVER['PHP_SELF'] ) ? sanitize_text_field( wp_unslash( $_SERVER['PHP_SELF'] ) ) : '';

    // 直接验证WordPress登录Cookie,替代is_user_logged_in()
    $is_logged_in = false;
    $cookie_name = 'wordpress_logged_in_' . COOKIEHASH;
    
    if ( isset( $_COOKIE[ $cookie_name ] ) ) {
        $cookie_parts = explode( '|', $_COOKIE[ $cookie_name ] );
        // 登录Cookie的结构为:user_id|expiration|token|hashed_password
        if ( count( $cookie_parts ) === 4 ) {
            $user_id = absint( $cookie_parts[0] );
            $user = get_userdata( $user_id );
            
            if ( $user && wp_check_password( $user->user_pass, $cookie_parts[3], $user->ID ) ) {
                $is_logged_in = true;
            }
        }
    }

    if ( ! strpos( $current_url, 'wp-admin' ) && ! $is_logged_in ) {
        return '/';
    }

    return $url;
}

代码说明

  1. Cookie结构解析:WordPress的登录Cookie命名为wordpress_logged_in_{COOKIEHASH},格式为用户ID|过期时间|令牌|密码哈希
  2. 验证逻辑:读取Cookie后拆分字段,通过get_userdata()获取用户信息,再用wp_check_password()验证Cookie中的哈希与用户密码是否匹配,以此判断用户是否登录
  3. 优势:无需提前加载pluggable.php,不会破坏插件对可插拔函数的扩展机制,同时能准确判断登录状态

备选方案:调整钩子优先级(谨慎使用)

若场景允许,可将wp_redirect钩子的优先级调低(如设置为99),确保在pluggable.php加载后再执行回调:

add_filter( 'wp_redirect', 'my_prefix_wp_redirect', 99 );

注意:此方法不保证所有wp_redirect调用都能在pluggable.php加载后触发,部分早期触发的跳转仍会报错,因此优先推荐Cookie验证方案。

内容的提问来源于stack exchange,提问作者Syed Ali Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:15:36