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.

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

}
Misha Rudrastyh

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

Follow me on X