Вопрос или проблема
Я использую wp_login_form()
для отображения формы входа в окно диалога jQuery.
Если пользователь вводит неправильный пароль, он попадает в бэкэнд. Я этого не хочу. Есть ли способ уведомить пользователя о неправильном пароле и остаться на той же странице?
До появления wp_login_form()
я использовал плагин. Надеюсь, что смогу обойтись без плагина на этот раз.
Мой код:
wp_login_form( array(
'label_remember' => __( 'Запомнить меня' ),
'label_log_in' => __( 'Вход' )
) );
wp_login_form()
создает форму с атрибутом action site_url/wp-login.php
, что означает, что при нажатии на кнопку отправки форма отправляется на site_url/wp-login.php
, который игнорирует redirect_to при ошибках (например, неправильный пароль), поэтому в вашем случае либо возвращайтесь к использованию плагина, либо воссоздайте весь процесс входа, и таким образом вы получите контроль над ошибками. Посмотрите на Проверка правильного имени пользователя в пользовательской форме входа, который является очень похожим вопросом.
Я пришел сюда из Google. Но ответ меня не удовлетворил. Я искал некоторое время и нашел лучшее решение.
Добавьте это в ваш functions.php:
add_action( 'wp_login_failed', 'my_front_end_login_fail' ); // hook на провал входа
function my_front_end_login_fail( $username ) {
$referrer = $_SERVER['HTTP_REFERER']; // откуда пришло сообщение?
// если есть допустимая ссылка и это не экран входа по умолчанию
if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') ) {
wp_redirect( $referrer . '?login=failed' ); // добавим некоторую информацию (login=failed) в URL, доступную для темы
exit;
}
}
Текущий метод, который я использую для обработки всех указанных здесь проблем, отлично работает даже с пустыми именем пользователя/паролем и не полагается на JavaScript (хотя JS может быть полезен вместе с этим).
add_action( 'wp_login_failed', 'custom_login_failed' );
function custom_login_failed( $username )
{
$referrer = wp_get_referer();
if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer,'wp-admin') )
{
wp_redirect( add_query_arg('login', 'failed', $referrer) );
exit;
}
}
Ключ – это этот фильтр для изменения обработки пустого имени пользователя/пароля:
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3);
function custom_authenticate_username_password( $user, $username, $password )
{
if ( is_a($user, 'WP_User') ) { return $user; }
if ( empty($username) || empty($password) )
{
$error = new WP_Error();
$user = new WP_Error('authentication_failed', __('<strong>ОШИБКА</strong>: Неправильное имя пользователя или неверный пароль.'));
return $error;
}
}
Вы можете пойти еще дальше и полностью заменить wp-login.php, перенаправляя пользователей на вашу пользовательскую страницу входа и использовать эту страницу также для перенаправления на login_failed. Полный код:
/**
* Действия на странице входа
*/
// Изменение URL входа по всему сайту на пользовательскую страницу входа
add_filter( 'login_url', 'custom_login_url', 10, 2 );
// Перенаправляет wp-login на пользовательскую страницу входа с некоторыми пользовательскими переменными ошибок, когда это необходимо
add_action( 'login_head', 'custom_redirect_login', 10, 2 );
// Обновляет login_failed для отправки пользователя обратно на пользовательскую форму с переменной
add_action( 'wp_login_failed', 'custom_login_failed', 10, 2 );
// Обновляет аутентификацию, чтобы вернуть ошибку, когда одно или оба поля пусты
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3);
// Автоматически добавляет форму входа на страницу "вход"
add_filter( 'the_content', 'custom_login_form_to_login_page' );
/**
* Функции пользовательской страницы входа
*/
function custom_login_url( $login_url="", $redirect="" )
{
$page = get_page_by_path('login');
if ( $page )
{
$login_url = get_permalink($page->ID);
if (! empty($redirect) )
$login_url = add_query_arg('redirect_to', urlencode($redirect), $login_url);
}
return $login_url;
}
function custom_redirect_login( $redirect_to='', $request="" )
{
if ( 'wp-login.php' == $GLOBALS['pagenow'] )
{
$redirect_url = custom_login_url();
if (! empty($_GET['action']) )
{
if ( 'lostpassword' == $_GET['action'] )
{
return;
}
elseif ( 'register' == $_GET['action'] )
{
$register_page = get_page_by_path('register');
$redirect_url = get_permalink($register_page->ID);
}
}
elseif (! empty($_GET['loggedout']) )
{
$redirect_url = add_query_arg('action', 'loggedout', custom_login_url());
}
wp_redirect( $redirect_url );
exit;
}
}
function custom_login_failed( $username )
{
$referrer = wp_get_referer();
if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer, 'wp-admin') )
{
if ( empty($_GET['loggedout']) )
wp_redirect( add_query_arg('action', 'failed', custom_login_url()) );
else
wp_redirect( add_query_arg('action', 'loggedout', custom_login_url()) );
exit;
}
}
function custom_authenticate_username_password( $user, $username, $password )
{
if ( is_a($user, 'WP_User') ) { return $user; }
if ( empty($username) || empty($password) )
{
$error = new WP_Error();
$user = new WP_Error('authentication_failed', __('<strong>ОШИБКА</strong>: Неправильное имя пользователя или неверный пароль.'));
return $error;
}
}
function custom_login_form_to_login_page( $content )
{
if ( is_page('login') && in_the_loop() )
{
$output = $message = "";
if (! empty($_GET['action']) )
{
if ( 'failed' == $_GET['action'] )
$message = "Проблема с вашим именем пользователя или паролем.";
elseif ( 'loggedout' == $_GET['action'] )
$message = "Вы вышли из аккаунта.";
elseif ( 'recovered' == $_GET['action'] )
$message = "Проверьте свой e-mail для получения ссылки подтверждения.";
}
if ( $message ) $output .= '<div class="message"><p>'. $message .'</p></div>';
$output .= wp_login_form('echo=0&redirect=". site_url());
$output .= "<a href="'. wp_lostpassword_url( add_query_arg('action', 'recovered', get_permalink()) ) .'" title="Восстановление забытого пароля">Забыли пароль?</a>';
$content .= $output;
}
return $content;
}
Настройте и добавьте эти элементы, чтобы добавить свой логотип на страницу wp-login для восстановления пароля:
// вызывается только на странице входа
add_action( 'login_enqueue_scripts', 'custom_login_css', 10 );
function custom_login_css() { wp_enqueue_style( 'custom_login_css', get_template_directory_uri() .'/library/css/login.css', false ); }
// изменяет ссылку логотипа с wordpress.org на ваш сайт
add_filter( 'login_headerurl', 'custom_login_logo_url' );
function custom_login_logo_url() { return home_url(); }
// изменяет альтернативный текст логотипа на название вашего сайта
add_filter( 'login_headertitle', 'custom_login_title' );
function custom_login_title() { return get_option('blogname'); }
CSS для логотипа входа:
.login h1 a {
background: url(../images/login-logo.png) no-repeat top center;
width: 274px;
height: 63px;
text-indent: -9999px;
overflow: hidden;
padding-bottom: 15px;
display: block;
}
ИЗМЕНЕНИЕ: Я только что реализовал это на другом сайте с нуля и обнаружил, что описанное выше “дальнейшее расширение” более полное, и исправил небольшие синтаксические ошибки в “add_actions”. Добавил некоторые комментарии и метод для автоматического добавления формы входа на страницу входа без отдельного файла шаблона. Метод формы входа должен работать в большинстве случаев, так как он прикреплен к “the_content”, это может вызвать проблему, если у вас на странице входа больше чем один цикл, в этом случае просто используйте шаблон page-login.php.
Решение для замечания Щепана Холышевского о пустых полях в принятом решении. Следующий jQuery предотвратит переход на стандартную страницу wp-login: (добавьте в шаблон страницы входа или footer.php)
jQuery("#loginform-custom").submit(function(){
var isFormValid = true;
jQuery("input").each(function()
{
if (jQuery.trim($(this).val()).length == 0){
jQuery(this).addClass("submit_error");
isFormValid = false;
}
else {
jQuery(this).removeClass("submit_error");
}
});
return isFormValid;
});
Следующее сработало для меня. Оба этих хука можно найти внутри функции wp_authenticate
в wp-includes/pluggable.php
.
- Проверяйте через фильтр
authenticate
, если в форме входа отсутствуют имя пользователя или пароль.
function wpse_15633_redirectMissingDataLoginForm($user, $username, $password)
{
$errors = [];
empty(trim($password)) && $errors[] = 'password_empty';
empty(trim($username)) && $errors[] = 'username_empty';
if (! empty($errors)) {
$redirect_url = add_query_arg([
'errors' => join(',', $errors),
], site_url('login', 'login_post'));
if (wp_safe_redirect($redirect_url)) {
exit;
}
}
return $user;
}
add_filter('authenticate', 'wpse_15633_redirectMissingDataLoginForm', 10, 3);
- Проверяйте через действие
wp_login_failed
, если аутентификация введенных имени пользователя и пароля не удалась.
function wpse_15633_redirectFailedLoginForm($username, $error)
{
$redirect_url = add_query_arg([
'errors' => $error->get_error_code(),
], site_url('login', 'login_post'));
if (wp_safe_redirect($redirect_url)) {
exit;
}
}
add_action('wp_login_failed', 'wpse_15633_redirectFailedLoginForm', 10, 2);
Одно дополнение к ответу Алексея. Вы можете добавить функцию jQuery для проверки того, что одно из полей не пусто. Таким образом, форма не будет отправлена, если в ней ничего нет для проверки, предотвращая перенаправление WordPress на /wp-login.php.
<script>
$("#wp-submit").click(function() {
var user = $("input#user_login").val();
if (user == "") {
$("input#user_login").focus();
return false;
}
});
</script>
Все еще не уверен, как исправить аспект восстановления пароля
Просто добавление к полезному ответу @алексея и добавление чего-то для решения упомянутой другими проблемы.
Его код для вставки в файл functions.php:
add_action( 'wp_login_failed', 'my_front_end_login_fail' ); // hook на провал входа
function my_front_end_login_fail( $username ) {
$referrer = $_SERVER['HTTP_REFERER']; // откуда пришло сообщение?
// если есть допустимая ссылка и это не экран входа по умолчанию
if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') ) {
wp_redirect( $referrer . '?login=failed' ); // добавим некоторую информацию (login=failed) в URL, доступную для темы
exit;
}
}
Однако, как заметили другие, если поля пустые, WordPress не проверяет и пользователи все равно попадают на экран входа в бэкэнд.
Чтобы обойти это, я добавляю скрипт сразу после создания формы, который добавляет required
к полям, чтобы браузер остановил любую отправку, если поля пустые.
На странице с вашей формой:
<?php
$args = array(
'form_id' => 'ВАШЕ-ИМЯ-ФОРМЫ',
);
wp_login_form( $args );
?>
<script>
if(jQuery('form#ВАШЕ-ИМЯ-ФОРМЫ').length) {
jQuery('form#ВАШЕ-ИМЯ-ФОРМЫ input').each(function() {
jQuery(this).attr("required", true);
});
}
</script>
Я хотел, чтобы в случае неудачной попытки входа (или пустого поля) пользователь оставался на той же странице с сообщением об ошибке. Я пытался использовать приведенный выше код, но в нем есть несколько ошибок… вы нашли более простой способ сделать это? Спасибо.
jQuery("#loginform-custom").submit(function(){
var isFormValid = true;
jQuery("input").each(function()
{
if (jQuery.trim($(this).val()).length == 0){
jQuery(this).addClass("submit_error");
isFormValid = false;
}
else {
jQuery(this).removeClass("submit_error");
}
});
return isFormValid;
});
.
Ответ или решение
Когда пользователь вводит неправильный пароль на вашем сайте на WordPress, стандартная реакция системы заключается в перенаправлении пользователя на страницу административного входа (wp-login.php), что может не соответствовать вашим требованиям, если вы хотите, чтобы пользователь оставался на той же странице и получал уведомления об ошибке. Давайте рассмотрим, как можно изменить это поведение, избегая использования сторонних плагинов.
Теория:
Основная задача заключается в том, чтобы перенаправлять пользователя на ту же страницу, на которой он попытался войти, при этом добавляя в URL параметр ошибок, чтобы отобразить соответствующее сообщение. В WordPress можно использовать хуки wp_login_failed
и authenticate
, чтобы определить сценарии, когда происходит неудачная попытка аутентификации.
Пример:
Мы можем воспользоваться хуками в WordPress для изменения логики обработки неудачных входов. Например, с помощью хука wp_login_failed
можно выполнить перенаправление при неудачной аутентификации:
add_action('wp_login_failed', 'redirect_failed_login');
function redirect_failed_login($username) {
$referrer = wp_get_referer(); // Узнаем, с какой страницы была отправлена форма.
// Проверяем, что есть реферер и он не ведет на страницы wp-login или wp-admin.
if (!empty($referrer) && !strstr($referrer, 'wp-login') && !strstr($referrer, 'wp-admin')) {
wp_redirect($referrer . '?login=failed'); // Перенаправляем на исходную страницу с параметром ошибки.
exit;
}
}
add_filter('authenticate', 'check_blank_fields', 30, 3);
function check_blank_fields($user, $username, $password) {
if (is_a($user, 'WP_User')) return $user;
if (empty($username) || empty($password)) {
$error = new WP_Error();
$error->add('authentication_failed', __('<strong>Ошибка</strong>: Неправильное имя пользователя или пароль.'));
return $error;
}
return $user;
}
Применение:
Этот код следует добавить в файл functions.php
вашей темы. Он использует механизм хуков WordPress для обработки ошибок аутентификации. Когда вход не удается, пользователь перенаправляется обратно на страницу, с которой он пытался войти, а в URL добавляется параметр ошибки ?login=failed
. Это позволяет вам отображать на этой странице сообщение об ошибке, используя этот параметр.
Так же можно добавить верификацию на стороне клиента с помощью JavaScript или jQuery, чтобы предотвратить отправку формы с пустыми полями, например, проверяя наличие текста во всех обязательных полях перед отправкой формы:
jQuery(document).ready(function($){
$('form#loginform').on('submit', function() {
var valid = true;
$(this).find('input[type="text"], input[type="password"]').each(function(){
if ($.trim($(this).val()) === '') {
$(this).addClass('error');
valid = false;
} else {
$(this).removeClass('error');
}
});
return valid;
});
});
Заключение:
При реализации решения по перенаправлению пользователя важно понимать контекст использования, интерфейс и возможные пользовательские сценарии. Помимо серверной логики, для улучшения пользовательского опыта также рекомендуется использовать клиентские проверки, предотвращающие отправку пустых форм. Убедитесь, что ваша страница корректно обрабатывает URL-параметры и отображает соответствующие сообщения пользователю. Эти изменения помогут сделать процесс входа более удобным и понятным для ваших пользователей, что увеличит их удовлетворенность и улучшит общий UX вашего сайта.