Вопрос или проблема
Я использую вход в WordPress через AJAX без плагина.
Я хочу запретить пользователям доступ к профилю WordPress после входа, потому что я разработал конкретный профиль по ссылке: http://www.domain.com/profile
. Поэтому я использую следующий код. Когда я добавляю следующий код в файл function.php, AJAX-вход не работает.
// Перенаправить пользователя на страницу profile.php
add_action('init' , 'prevent_profile_access');
function prevent_profile_access(){
if (current_user_can('manage_options')) return '';
if (strpos($_SERVER ['REQUEST_URI'] , 'wp-admin' )){
wp_redirect ("http://www.domain.com/profile");
}
if (strpos($_SERVER ['REQUEST_URI'] , 'wp-login.php' )){
wp_redirect ("http://www.domain.com/profile");
}
}
Как мне решить эту проблему?
Мои коды AJAX-входа:
HTML:
<form id="login" action="login" method="post">
<h1>Вход на сайт</h1>
<p class="status"></p>
<label for="username">Имя пользователя</label>
<input id="username" type="text" name="username">
<label for="password">Пароль</label>
<input id="password" type="password" name="password">
<a class="lost" href="https://wordpress.stackexchange.com/questions/183668/<?php echo wp_lostpassword_url(); ?>">Забыли пароль?</a>
<input class="submit_button" type="submit" value="Войти" name="submit">
<a class="close" href="">(закрыть)</a>
<?php wp_nonce_field( 'ajax-login-nonce', 'security' ); ?>
</form>
PHP(function.php):
function ajax_login_init(){
wp_register_script('ajax-login-script', get_template_directory_uri() . '/ajax-login-script.js', array('jquery') );
wp_enqueue_script('ajax-login-script');
wp_localize_script( 'ajax-login-script', 'ajax_login_object', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'redirecturl' => home_url(),
'loadingmessage' => __('Отправка информации пользователя, пожалуйста подождите...')
));
// Разрешить пользователю без привилегий запускать ajax_login() в AJAX
add_action( 'wp_ajax_nopriv_ajaxlogin', 'ajax_login' );
}
// Выполнить действие только если пользователь не вошел в систему
if (!is_user_logged_in()) {
add_action('init', 'ajax_login_init');
}
function ajax_login(){
// Сначала проверяем nonce, если проверка не пройдет, функция завершится
check_ajax_referer( 'ajax-login-nonce', 'security' );
// Nonce проверен, получаем данные POST и вход в систему
$info = array();
$info['user_login'] = $_POST['username'];
$info['user_password'] = $_POST['password'];
$info['remember'] = true;
$user_signon = wp_signon( $info, false );
if ( is_wp_error($user_signon) ){
echo json_encode(array('loggedin'=>false, 'message'=>__('Неверное имя пользователя или пароль.')));
} else {
echo json_encode(array('loggedin'=>true, 'message'=>__('Вход выполнен успешно, перенаправление...')));
}
die();
}
AJAX(ajax-login-script.js):
jQuery(document).ready(function($) {
// Показать диалоговое окно входа по клику
$('a#show_login').on('click', function(e){
$('body').prepend('<div class="login_overlay"></div>');
$('form#login').fadeIn(500);
$('div.login_overlay, form#login a.close').on('click', function(){
$('div.login_overlay').remove();
$('form#login').hide();
});
e.preventDefault();
});
// Выполнить AJAX-вход при отправке формы
$('form#login').on('submit', function(e){
$('form#login p.status').show().text(ajax_login_object.loadingmessage);
$.ajax({
type: 'POST',
dataType: 'json',
url: ajax_login_object.ajaxurl,
data: {
'action': 'ajaxlogin', // вызывает wp_ajax_nopriv_ajaxlogin
'username': $('form#login #username').val(),
'password': $('form#login #password').val(),
'security': $('form#login #security').val() },
success: function(data){
$('form#login p.status').text(data.message);
if (data.loggedin == true){
document.location.href = ajax_login_object.redirecturl;
}
}
});
e.preventDefault();
});
});
Вам нужно подключить это позже.
add_action('template_redirect' , 'prevent_profile_access');
Ссылки:
https://codex.wordpress.org/Plugin_API/Action_Reference
https://codex.wordpress.org/Plugin_API/Action_Reference/template_redirect
Ответ или решение
Конечно, давайте рассмотрим детали вашей проблемы с использованием AJAX для входа в WordPress без плагина и того, как обеспечить корректную работу системы авторизации, при этом ограничивая доступ к стандартному профилю.
Проблема
Вы используете AJAX для авторизации пользователей, однако добавление функции перенаправления в functions.php
нарушает работу AJAX-входа. Вы хотите, чтобы после входа пользователь перенаправлялся на страницу профиля, и, в то же время, предотвращали доступ к стандартным профилям WordPress.
Анализ кода
Ваш текущий код для перенаправления пользователей выглядит следующим образом:
add_action('init', 'prevent_profile_access');
function prevent_profile_access() {
if (current_user_can('manage_options')) return '';
if (strpos($_SERVER['REQUEST_URI'], 'wp-admin')) {
wp_redirect("http://www.domain.com/profile");
exit; // Необходимо добавить exit для предотвращения дальнейшего выполнения
}
if (strpos($_SERVER['REQUEST_URI'], 'wp-login.php')) {
wp_redirect("http://www.domain.com/profile");
exit;
}
}
Проблема перенаправления
Перенаправление выполняется на этапе init
, что приводит к его срабатыванию и при AJAX-запросах. Это вызывает проблемы, так как AJAX не может корректно обработать перенаправление (ожидает JSON ответ, а не HTTP-редирект).
Решение
Чтобы исправить данную проблему, необходимо использовать другой хук, такой как template_redirect
, который выполняется до окончательной обработки страницы, а не на этапе инициализации.
Правильный подход
Вот так можно модифицировать ваш код:
add_action('template_redirect', 'prevent_profile_access');
function prevent_profile_access() {
if (current_user_can('manage_options')) return;
if (strpos($_SERVER['REQUEST_URI'], 'wp-login.php') !== false || strpos($_SERVER['REQUEST_URI'], 'wp-admin') !== false) {
wp_redirect("http://www.domain.com/profile");
exit;
}
}
Поддержка AJAX
Также следует убедиться, что ваш AJAX-запрос корректно перенаправляет пользователя после успешного входа. В вашем коде AJAX вы задаете редирект, используя переменную redirecturl
, которая в данный момент настроена на home_url()
. Вам нужно изменить значение этой переменной на нужный URL.
Измените ваш PHP код для локализации скрипта следующим образом:
wp_localize_script('ajax-login-script', 'ajax_login_object', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'redirecturl' => "http://www.domain.com/profile", // Укажите свой URL профиля
'loadingmessage' => __('Sending user info, please wait...')
));
Итог
- Перенаправление реализовано с использованием хука
template_redirect
, что позволяет избежать нежелательных редиректов в AJAX. - Обновите значение
redirecturl
для перенаправления пользователей на нужную страницу после успешного входа.
Эти изменения помогут вашему AJAX-входу функционировать правильно, обеспечивая при этом сохранение желаемого поведения с перенаправлениями. Если у вас есть дополнительные вопросы или требуется дальнейшая помощь, не стесняйтесь обращаться.