Send WordPress users a link to sign in by email instead using passwords
On this weekend I was at WordCamp Oslo 🇳🇴, so I didn’t have enough time to prepare a super-tutorial for you guys, but this will be something like a small tip.
I decided to put all the code to a single file, but you can separate it into different ones.
/*
* Template name: No more passwords
*/
// redirect already logged in users to member's area (I redirect to admin area but it could be anything else)
if( is_user_logged_in() ) {
wp_redirect( admin_url() );
exit;
}
// check if we're submitting the form at this moment
if( !empty( $_POST[ 'misha_email' ] )
&& ( $user_data = get_user_by( 'email', $_POST[ 'misha_email' ] ) ) // if user exists
&& !is_wp_error( $key = get_password_reset_key( $user_data ) ) ) { // get his activation key
// create a login URL like this http://YOUR-WEBSITE.COM/login?key=KEY&email=EMAIL
$login_url = add_query_arg( array(
'key' => $key,
'email' => rawurlencode( $user_data->user_email )
), site_url('login') );
// email headers, use your website domain in From header
$headers = array(
'From: Misha <no-reply@YOUR-WEBSITE.COM>',
'Content-type: text/html; charset=utf-8'
);
// in headers we set content-type to text/html, so feel free to use any HTML tags
$message = 'Here is you link to login <a href="' . $login_url . '">' . $login_url . '</a>';
// WordPress default function to send emails
wp_mail( $user_data->user_email, 'Sign in to YOUR-WEBSITE.COM', $message, $headers );
// no matter if email is sent or not, redirect users to a success message
// btw - wp_mail() returns true when emails sent successfully, you can use it
wp_redirect( add_query_arg('status', 'sent', site_url('login') ) );
exit;
} else if( !empty( $_GET['key'] ) && !empty($_GET['email']) ) {
// if we're NOT submitting the form, we can perform a check for $_GET parameters that are part of the login link
// if user with this email exists and the key is correct
if( ( $user_data = get_user_by( 'email', $_GET['email'] ) )
&& ( !is_wp_error( $check = check_password_reset_key( wp_unslash( $_GET['key']), $user_data->user_login ) ) ) ) {
wp_set_auth_cookie( $check->data->ID, true, false );
// $check->data->ID – user ID
// true – remember checkbox
// false – if you're using SSL on the website, set to true!
wp_redirect( admin_url() );
exit;
} else {
echo 'You auth link is expired or incorrect, please try again.';
}
}
if( isset( $_GET['status'] ) && $_GET['status'] == 'sent' ) {
echo 'If this email is registered on the website, please check your inbox.';
}
// so simple form :)
echo '<form action="" method="POST"><input type="email" name="misha_email" /><button>Send login link</button</form>';
And the last thing I want you to know is that you can change the link expiration time with password_reset_expiration
action hook (defaults to 1 day)
add_filter( 'password_reset_expiration', 'misha_custom_activation_link_period', 9999 );
function misha_custom_activation_link_period( $day_in_seconds ){
return 900; // 15 minutes
}

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
This should be used as a 2-step authentication, but not a way to bypass the password.
By default is is just the part of the password reset functionality.
I can be used different ways depending on the website. For some projects you can bypass the password with it, for the other ones – for 2-step auth.
By the way, for 2 step authentication it is better to use this solution (confirmation by mobile is better than by email, you should be agreed with me).