So Wordfence uses JavaScript to add the CAPTCHA fields to the login/registration form, but by default only on https://example.com/wp-login.php
.
And if you want to add the fields to your form, or integrate the CAPTCHA security with your custom login form, the steps are:
Enqueue the (re)CAPTCHA scripts, preferably only on the page having the custom form:
add_action( 'wp_enqueue_scripts', function () {
if ( is_page( 'my-page' ) &&
class_exists( '\WordfenceLS\Controller_WordfenceLS' )
) {
\WordfenceLS\Controller_WordfenceLS::shared()->_login_enqueue_scripts();
}
} );
The above would load the scripts only on the my-page
Page, so you should change the slug or use another conditional tag like is_single()
.
Your custom form has to meet these conditions:
The username field must be named log
(e.g. <input name="log" />
).
The password field must be named pwd
(e.g. <input name="pwd" />
).
The submit button's id
must be wp-submit
(e.g. <input id="wp-submit" type="submit" />
).
There must be no other forms having those fields, i.e. there must be no other form fields having the same name
or id
.
Wordfence will run an AJAX request to check the credentials and when there's an error like wrong password, Wordfence will add the error message after a h1
(heading level 1) inside the element with the id
of login
.
So you need to make sure those two elements (#login
and #login > h1
) both exist — see the sample form code below.
And those are, unfortunately, limitations in the Wordfence's custom login script, which you can find it in wp-content/plugins/wordfence/modules/login-security/js
and the file name looks like login.1581523568.js
(i.e. login.<numbers>.js
). You may copy and modify the script (i.e. remove those 5 limitations), then enqueue it instead of the default, but you'll need to try doing so on your own.
Also, if you use wp_login_form()
(with a custom action
value), you would only need to add the elements mentioned in #5 above.
Code I used for testing:
The form, shown on https://example.com/my-page/
:
<div id="login">
<h1>Login</h1>
<!-- Wordfence places AJAX error here -->
<form method="post" action="">
<input name="log" type="text" placeholder="Username" />
<input name="pwd" type="password" placeholder="Password" />
<input type="hidden" name="action" value="my_login" />
<?php wp_nonce_field( 'my-login' ); ?>
<input type="submit" id="wp-submit" />
</form>
</div>
And the PHP, which calls wp_signon()
:
add_action( 'init', function () {
if (
wp_doing_ajax() || empty( $_POST['_wpnonce'] ) ||
( ! ( isset( $_POST['log'], $_POST['pwd'] ) ) ) ||
! wp_verify_nonce( $_POST['_wpnonce'], 'my-login' )
) {
return;
}
$creds = array();
$creds['user_login'] = $_POST['log'];
$creds['user_password'] = $_POST['pwd'];
$creds['remember'] = true;
$user = wp_signon( $creds, false );
if ( is_wp_error( $user ) ) {
wp_die( $user );
} else {
wp_redirect( home_url( wp_get_referer() ) );
exit;
}
} );
Additional Notes
As I mentioned in the comment, if you just want to bypass the CAPTCHA validation while doing wp_signon()
, you can use the wordfence_ls_require_captcha
filter:
add_filter( 'wordfence_ls_require_captcha', '__return_false' );
// call wp_signon() here
remove_filter( 'wordfence_ls_require_captcha', '__return_false' );
wordfence_ls_require_captcha
. Have you tried that?wp_signon()
. But if you actually want to add the captcha to your custom form, then you can ignore that filter.