I want to create a function that will halt the login process in wordpress and let a user to validate an otp form or code before he logins in fully. And i intend this interception to be just after the users email and password
This is what i tried
add_filter( 'authenticate', 'smyles_check_custom_auth', 10, 3 );
function smyles_check_custom_auth( $user, $username, $password ){
$otp_check = 'bad'; // variable returned from query but just using bad for testing
if( !$otp_check == 'good' ){
return confirm_form();
}
elseif($otp_check == 'good'){
return $user;
}
return new WP_Error( __( 'OTP Check failed' ) );
}
Yet it did not work out, it only stops the form from validating without any error message shown if i set my priority at 20,3
My goal is to allow the username and password to get validated first, and then the submit button and the username and password field will be disabled and my confirm otp code will been shown, once the user confirms the right otp he then the login process continues which is the redirect process hopefully to the admin. If i set the priority level to 10, 3 the form gets submitted and user logins in no matter what code i have.
Workflow is this:
So all my problem is to know a hook that i can hook in my otp confirm _form() so it executed after user name and password authication but before the action wpsignon() is called. Just a middle interception.
I want to create a function that will halt the login process in wordpress and let a user to validate an otp form or code before he logins in fully. And i intend this interception to be just after the users email and password
This is what i tried
add_filter( 'authenticate', 'smyles_check_custom_auth', 10, 3 );
function smyles_check_custom_auth( $user, $username, $password ){
$otp_check = 'bad'; // variable returned from query but just using bad for testing
if( !$otp_check == 'good' ){
return confirm_form();
}
elseif($otp_check == 'good'){
return $user;
}
return new WP_Error( __( 'OTP Check failed' ) );
}
Yet it did not work out, it only stops the form from validating without any error message shown if i set my priority at 20,3
My goal is to allow the username and password to get validated first, and then the submit button and the username and password field will be disabled and my confirm otp code will been shown, once the user confirms the right otp he then the login process continues which is the redirect process hopefully to the admin. If i set the priority level to 10, 3 the form gets submitted and user logins in no matter what code i have.
Workflow is this:
So all my problem is to know a hook that i can hook in my otp confirm _form() so it executed after user name and password authication but before the action wpsignon() is called. Just a middle interception.
Yes there is an authenticate
filter you can hook into in the wp_authenticate
function, and return a WP_Error
if the login fails.
/**
* Filters whether a set of user login credentials are valid.
*
* A WP_User object is returned if the credentials authenticate a user.
* WP_Error or null otherwise.
*
* @since 2.8.0
* @since 4.5.0 `$username` now accepts an email address.
*
* @param null|WP_User|WP_Error $user WP_User if the user is authenticated.
* WP_Error or null otherwise.
* @param string $username Username or email address.
* @param string $password User password
*/
$user = apply_filters( 'authenticate', null, $username, $password );
This is exactly how WordPress internally validates username and password, these are the default filters used:
add_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
add_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 );
add_filter( 'authenticate', 'wp_authenticate_spam_check', 99 );
I recommend setting your filter to priority of 10, or something less than 20 (which is when username/password is checked), so your check is ran first.
If your test passes, just return the first variable passed, for example:
add_filter( 'authenticate', 'smyles_check_custom_auth', 10, 3 );
function smyles_check_custom_auth( $user, $username, $password ){
$otp_check = false;
if( $otp_check ){
return $user;
}
return new WP_Error( __( 'OTP Check failed' ) );
}