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() );

// 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') ) );

} 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() );

	} 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

I develop websites since 2008, so it is total of 13 years of experience, oh my gosh. Most of all I love love love to create websites with WordPress and Gutenberg, some ideas and thoughts I share throughout my blog.

Need some developer help? Contact me