如何在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; }
代码说明
- Cookie结构解析:WordPress的登录Cookie命名为
wordpress_logged_in_{COOKIEHASH},格式为用户ID|过期时间|令牌|密码哈希 - 验证逻辑:读取Cookie后拆分字段,通过
get_userdata()获取用户信息,再用wp_check_password()验证Cookie中的哈希与用户密码是否匹配,以此判断用户是否登录 - 优势:无需提前加载
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
相关产品推荐
相关产品推荐

