Send WordPress users a link to sign in by email instead using passwords

In this tutorial we’re creating a custom login form that allows to sign in WordPress users when they click a link in email.

/2 comments

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.

Our custom login page that allows users to receive the auth link to login.
Of course we won’t make any changes in WordPress wp-login.php file, but due the lack of hooks inside it, it is better to create a custom page template.

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
 
}

#users

Need some help with WordPress?

If you need some professional developer help, I will be happy to assist you.

Contact me Who I am?

Comments — 2

Leave a comment

php js HTML CSS Code