背景
我正在尝试为博客创建一个无缝的前端登录,同时仍然离开 wp-login.php
提供给那些知道如何到达那里的用户。 wp-login.php
还需要对前端登录进行身份验证,因此无法将其完全删除。
我快到了,但我遇到登录失败的问题,特别是用户名为空。
问题
有谁知道既能停下来的方法 wp-login.php
显示为空的用户名/密码错误,同时避免在用户直接访问时以相同的原因显示错误 wp-login.php
?
我的工作
我找到了 wp_login_failed
钩子并创建了下面的函数。 基本上它添加了查询参数来说明登录失败以及在将用户重定向回前端登录之前输入的用户名。 使用查询参数,我可以确定登录失败的原因并向用户显示一条消息。
add_action('wp_login_failed', 'djg_front_end_login_fail');
function djg_front_end_login_fail($username){
$referrer = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : $_SERVER['PHP_SELF'];
$referrer = add_query_arg('result', 'failed', $referrer);
$referrer = add_query_arg('username', $username, $referrer);
if(!empty($referrer) && !strstr($referrer, 'wp-login') && !strstr($referrer, 'wp-admin')) :
wp_redirect($referrer);
exit;
endif;
}
但是,我注意到如果用户名字段为空,我不会被重定向,而是仍然显示用户 wp-login.php
.
经过进一步检查,我发现 wp_authenticate()
我注意到如果第一个登录错误是 empty_username
或者 empty_password
, 这 wp_login_failed
未添加动作挂钩。 为了解决这个问题,我使用了 authenticate
filter hook 并实际更改了上述错误的代码,在前面加上 djg_
对他们来说,这样他们就不会被忽视。
add_filter('authenticate', 'djg_authenticate_login', 99, 3);
function djg_authenticate_login($user, $username, $password){;
if(is_wp_error($user)) :
$codes = $user->get_error_codes();
$messages = $user->get_error_messages();
$user = new WP_Error;
for($i = 0; $i <= count($codes) - 1; $i++) :
$code = $codes[$i];
if(in_array($code, array('empty_username', 'empty_password'))) :
$code="djg_" . $code;
endif;
$user->add($code, $messages[$i]);
endfor;
endif;
return $user;
}
这行得通,但现在如果用户直接转到 wp-login.php
页面,该页面必须保持可用(如中所述 背景), 显示错误 –
错误:用户名字段为空。
错误:密码字段为空。
终于,在扯了很多头发之后,我发现了 wp_signon()
执行导致此问题的代码,但在我看来,我看不到任何过滤器可以让我在代码片段周围的任何地方更改行为。 基本上它是说如果错误是准确的 empty_username
和 empty_password
, 别理他们。 –
if ( is_wp_error($user) ) {
if ( $user->get_error_codes() == array('empty_username', 'empty_password') ) {
$user = new WP_Error('', '');
}
return $user;
}
细节
wp_authenticate()
位于/wp-includes/pluggable.php
- 这
authenticate
过滤器挂钩位于wp_authenticate()
功能 - 这
wp_login_failed
动作挂钩位于wp_authenticate()
功能 wp_signon()
位于/wp-includes/user.php
问题(再次)
有谁知道既能停下来的方法 wp-login.php
为空用户名错误显示,同时避免在用户直接访问时因相同原因显示错误 wp-login.php
?
WordPress 以两种方式处理登录失败:
- 如果它是一个错误的凭据,并且用户名和密码都有值,则可以通过以下方式捕获此操作
wp_login_failed
- 如果两个或其中一个选项为空,那么 WordPress 将生成错误对象作为身份验证过滤器中的第一个参数; 它不打开并且
wp_login_failed
动作捕捉这个原因/事件
对于我们在这里所做的,请参阅代码中的注释:
add_filter( 'authenticate', function( $user, $username, $password ) {
// forcefully capture login failed to forcefully open wp_login_failed action,
// so that this event can be captured
if ( empty( $username ) || empty( $password ) ) {
do_action( 'wp_login_failed', $user );
}
return $user;
}, 10, 3 );
// to handle even you can handle the error like
add_action( 'wp_login_failed', function( $username ) {
if ( is_wp_error( $username ) ) {
// perform operation on error object for empty error
}
} );
