Freddy
Freddy

Reputation: 867

WooCommerce: "This key is invalid ..." error

I've created a custom reset password page on my WooCommerce site. The reset page was previously /my-account/lost-password/, but my custom page is /reset-password/.

In my theme, I've copied over the WooCommerce customer-reset-password.php so I could customise the URL in the email to point to my new page. The link in the email looks like this:

<a class="link" href="<?php echo esc_url( add_query_arg( array( 'key' => $reset_key, 'id' => $user_id ), home_url()." /reset-password/ " ) ); ?>">
  <?php // phpcs:ignore ?>
  <?php esc_html_e( 'Click here to reset your password', 'woocommerce' ); ?>
</a>

Now, when I go to /lost-password/, and enter my email address. I successfully receive a reset email with the link pointing to the correct page: /reset-password/?key=p5iemdCVtG4qkh5WQH8B&id=31

Upon clicking on the link in the email, I can then enter my new password and re-enter new password (I'm using the WooCommerce reset_password_form shortcode to show the form).

However, when filling out these fields, and clicking submit, I get the following message: This key is invalid or has already been used. Please reset your password again if needed.

I've had a look into existing threads, namely:

Unsure how to proceed?

How I've created / added the reset password form:

  1. Registered the WooCommerce reset password shortcode in functions.php

function wc_custom_reset_password_form( $atts ) {
  return wc_get_template( 'myaccount/form-reset-password.php', array( 'form' => 'reset_password' ) );
}
add_shortcode( 'reset_password_form', 'wc_custom_reset_password_form' );

  1. Added the shortcode to my template:

<?php echo do_shortcode( '[reset_password_form]' ); ?>

What's been changed in customer-reset-password.php?

This is what the template has as the link by default:

<a class="link" href="<?php echo esc_url( add_query_arg( array( 'key' => $reset_key, 'id' => $user_id ), wc_get_endpoint_url( 'lost-password', '', wc_get_page_permalink( 'myaccount' ) ) ) ); ?>"><?php // phpcs:ignore ?>
  <?php esc_html_e( 'Click here to reset your password', 'woocommerce' ); ?>
</a>

This is what I changed it to:

<a class="link" href="<?php echo esc_url( add_query_arg( array( 'key' => $reset_key, 'id' => $user_id ), home_url()." /reset-password/ " ) ); ?>">
  <?php // phpcs:ignore ?>
  <?php esc_html_e( 'Click here to reset your password', 'woocommerce' ); ?>
</a>

Upvotes: 0

Views: 1907

Answers (2)

Gautam Golakiya
Gautam Golakiya

Reputation: 452

The reason it's not working and gives you an error because you were supposed to be pass key and user login into form-reset-password.php which you didn't when you call template file into your shortcode.

You have to just only add 'key' => $rp_key, 'login' => $rp_login.

Your current code is :

function wc_custom_reset_password_form( $atts ) {
  return wc_get_template( 'myaccount/form-reset-password.php', array( 'form' => 'reset_password' ) );
}
add_shortcode( 'reset_password_form', 'wc_custom_reset_password_form' );

Complete code :

function wc_custom_reset_password_form( $atts ) {
    $rp_key     = wp_unslash( $_GET['key'] );
    $user_id    = absint( $_GET['id'] );
    $userdata   = get_userdata( absint( $user_id ) );
    $rp_login   = $userdata ? $userdata->user_login : '';
    $user       = WC_Shortcode_My_Account::check_password_reset_key( $rp_key, $rp_login );  
    return wc_get_template( 'myaccount/form-reset-password.php', array( 'form' => 'reset_password', 'key' => $rp_key, 'login' => $rp_login ) );
}
add_shortcode( 'reset_password_form', 'wc_custom_reset_password_form' );

You can add your validation for key and user id ( from query parameter ) into this code.

Upvotes: 2

Rajeev Singh
Rajeev Singh

Reputation: 1809

You can try the following:

Your Custom Link:

<a class="link" href="<?php echo esc_url(add_query_arg(array('action' => 'rp','id' => $user_id), site_url('/')) ); ?>">

Now you can add anywhere on your site.

Add below code on functions.php

if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'rp') {
    $user_id   = isset($_REQUEST['id']) ? $_REQUEST['id'] : 0;
    $action    = $_REQUEST['action'];

    if($user_id ){
       $user_data = get_userdata( $user_id );

       $user_email = $user_data->user_email;
       $reset_key  = get_password_reset_key( $user_data );

       wp_redirect( site_url( 'wp-login.php' ) . '?action='. $action .'&key=' . $reset_key . '&login=' . $user_email );
      exit;
    }
 }

After clicking on the link, the output is:

enter image description here

Upvotes: 0

Related Questions