Вопрос или проблема
Я действительно пытаюсь внедрить Google Captcha V3 на страницу wp-login. Я видел, что этот фрагмент кода упоминался несколько раз в разных местах. Дело в том, что никто, кажется, не указывает, как проверить раздел, который говорит “// FIXME: Это срабатывает, если ваш пароль неправильный… Проверьте, был ли пароль неправильным, прежде чем возвращать эту ошибку…”
Можно ли сделать ajax проверку, чтобы узнать, правильный ли пароль пользователя?
Это было бы огромным активом для разработки WP.
/**
* Эти функции добавляют и проверяют невидимую Google reCAPTCHA на входе
*/
add_action('login_enqueue_scripts', 'login_recaptcha_script');
function login_recaptcha_script() {
wp_register_script('recaptcha_login', 'https://www.google.com/recaptcha/api.js');
wp_enqueue_script('recaptcha_login')
}
add_action( 'login_form', 'display_recaptcha_on_login' );
function display_recaptcha_on_login() {
echo "<script>
function onSubmit(token) {
document.getElementById('loginform').submit();
}
</script>
<button class="g-recaptcha" data-sitekey='YOUR_PUBLIC_KEY' data-callback='onSubmit' data-size="invisible" style="display:none;">Отправить</button>";
}
add_filter('wp_authenticate_user', 'verify_recaptcha_on_login', 10, 2);
function verify_recaptcha_on_login($user, $password) {
if (isset($_POST['g-recaptcha-response'])) {
$response = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=YOUR_SECRET_KEY&response=" . $_POST["g-recaptcha-response'] );
$response = json_decode($response['body'], true);
if (true == $response['success']) {
return $user;
} else {
// FIXME: Это срабатывает, если ваш пароль неправильный... Проверьте, был ли пароль неправильным, прежде чем возвращать эту ошибку...
// return new WP_Error( 'Captcha Invalid', __('<strong>ОШИБКА</strong>: Вы бот') );
}
} else {
return new WP_Error( 'Captcha Invalid', __('<strong>ОШИБКА</strong>: Вы бот. Если нет, то включите JavaScript.') );
}
}
Я не считаю нужным делать проверку пароля внутри фильтра wp_authenticate_user
, так как эта проверка выполняется следующим шагом внутри wp_authenticate_email_password()
, где определяется фильтр. Вы можете увидеть это в wp-includes/user.php#L168.
Параметр фильтра $user
является либо WP_User
, либо WP_Error
в зависимости от того, может ли пользователь быть найден по имени пользователя, использованному при входе. После фильтра есть проверка if ( is_wp_error( $user ) )
, которая, если пройдена, сопровождается проверкой if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) )
. Если эта проверка не проходит, пароль неправильный для этого имени пользователя, иначе заданные имя пользователя и пароль корректны.
Ответ или решение
Да, вопрос, который вы задали, касается одной из важных функций безопасности в WordPress — проверки пароля пользователя. В частности, вы ищете способ проверить корректность пароля в контексте использования фильтра wp_authenticate_user
, который применяется в процессе аутентификации.
При обработке аутентификации пользователя в WordPress функция wp_authenticate_email_password()
управляет основными проверками, включая проверку пароля. Эта функция сначала производит поиск пользователя по переданным учетным данным (например, email либо никнейм), а затем выполняет проверку пароля через wp_check_password()
. Именно поэтому, вызвать проверку пароля в фильтре wp_authenticate_user
может быть излишним, поскольку она уже реализована на более низком уровне.
Концепция проверки пароля
Фильтр wp_authenticate_user
позволяет модифицировать или расширить процесс аутентификации, но он не предназначен для выполнения самой проверки пароля. Этот фильтр принимает два параметра: $user
и $password
. Значение $user
может быть объектом WP_User
или объектом класса WP_Error
, в зависимости от результатов предыдущих проверок.
Согласно внутренней логике WordPress, если в фильтре вернется объект WP_Error
, это означает, что пользователь не обнаружен. В случае успешного прохождения этого этапа WordPress позже (в процессе выполнения wp_authenticate_email_password
) проверит, соответствует ли предоставленный пароль хешу пароля пользователя с использованием функции wp_check_password
. Таким образом, задача обработки пароля уже предусмотрена в рамках системы.
Реализация CAPTCHA
Теперь, по поводу интеграции Google reCAPTCHA v3 в процесс аутентификации: вы можете продолжать использовать verify_recaptcha_on_login
для проверки токена, полученного с клиентской стороны. Если токен действителен, вы можете вернуть объект пользователя. Если он недействителен, можно возвращать ошибку. Однако важно помнить, что проверка пароля уже выполняется в следующие строки кода, и на этом этапе нет необходимости добавлять дополнительную проверку пароля, так как она происходит позже.
Пример кода
Вот пример, как это может выглядеть:
add_filter('wp_authenticate_user', 'verify_recaptcha_on_login', 10, 2);
function verify_recaptcha_on_login($user, $password) {
if (isset($_POST['g-recaptcha-response'])) {
$response = wp_remote_get('https://www.google.com/recaptcha/api/siteverify?secret=YOUR_SECRET_KEY&response=' . $_POST["g-recaptcha-response"]);
$response_body = json_decode($response['body'], true);
if (true == $response_body['success']) {
return $user; // Процедура аутентификации продолжится
} else {
return new WP_Error('captcha_invalid', __('ERROR: You are a bot.'));
}
} else {
return new WP_Error('captcha_invalid', __('ERROR: Please enable JavaScript in your browser.'));
}
}
Заключение
В итоге, можно подтверждать корректность пароля на более позднем этапе, что уже предусмотрено в ядре WordPress. Использование фильтра wp_authenticate_user
целесообразно для работы с внешними проверками, такими как reCAPTCHA. Это подход будет оптимальным с точки зрения производительности и логической структуры кода. Надеюсь, данная информация поможет вам эффективно интегрировать Google CAPTCHA v3 в вашу программу аутентификации в WordPress.