简体   繁体   English

错误=WordPress 自定义密码恢复页面的无效密钥

[英]errors=invalidkey for a WordPress Custom Password recovery page

WordPress v5.4.1, I have the below code to send the password reset mail from custom page. WordPress v5.4.1,我有以下代码从自定义页面发送密码重置邮件。

Followed the https://code.tutsplus.com/tutorials/build-a-custom-wordpress-user-flow-part-3-password-reset--cms-23811 .遵循https://code.tutsplus.com/tutorials/build-a-custom-wordpress-user-flow-part-3-password-reset--cms-23811

// Custom message
function replace_retrieve_password_message($message, $key, $user_login, $user_data) {

    global $wpdb;

    $key = $wpdb->get_var("SELECT user_activation_key FROM $wpdb->users WHERE user_login ='" . $user_login . "'");
    if (empty($key)) {
        //generate reset key
        $key = wp_generate_password(20, false);
        $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
    }
    // Create new message
    $msg = __('Hello!') . "\r\n\r\n";
    $msg .= sprintf(__('You asked us to reset your password for your account using the email address %s.'), $user_login) . "\r\n\r\n";
    $msg .= __("If this was a mistake, or you didn't ask for a password reset, just ignore this email and nothing will happen.") . "\r\n\r\n";
    $msg .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    $msg .= site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . "\r\n\r\n";
    $msg .= __('Thanks!') . "\r\n";

    return $msg;
}

add_filter('retrieve_password_message', 'replace_retrieve_password_message', 10, 4);

User is getting the password reset email and while clicking on the link, it gives errors=invalidkey .用户正在获取密码重置 email 并在单击链接时给出errors=invalidkey
I have tried removing the custom $key function to have WordPress default key generation.我尝试删除自定义$key function 以生成 WordPress 默认密钥。 Then I will have password reset page, but any action is showing errors=invalidkey .然后我将有密码重置页面,但任何操作都显示errors=invalidkey

Why are you regenerating the $key ?你为什么要重新生成$key Why not just use the one passed to your callback?为什么不只使用传递给您的回调的那个?

But if you must regenerate it, then you could just use get_password_reset_key() :但是如果你必须重新生成它,那么你可以只使用get_password_reset_key()

$key = get_password_reset_key( $user_data );

The reason for your invalidkey error is that you are just creating the random password and using it as is.您的invalidkey错误的原因是您只是在创建随机密码并按原样使用它。 For it to be valid reset key it needs to be hashed.要使其成为有效的重置密钥,需要对其进行哈希处理。

Reference: https://core.trac.wordpress.org/browser/tags/5.4/src/wp-includes/user.php#L2316参考: https://core.trac.wordpress.org/browser/tags/5.4/src/wp-includes/user.php#L2316

So if you want to use your approach you just need to hash your key like this,因此,如果您想使用您的方法,您只需要像这样 hash 您的密钥,

// Custom message
function replace_retrieve_password_message($message, $key, $user_login, $user_data) {

    global $wpdb;
    global $wp_hasher;

    $key = $wpdb->get_var("SELECT user_activation_key FROM $wpdb->users WHERE user_login ='" . $user_login . "'");
    if (empty($key)) {
        //generate reset key
        $key = wp_generate_password(20, false);

        if ( empty( $wp_hasher ) ) {
            require_once ABSPATH . WPINC . '/class-phpass.php';
            $wp_hasher = new PasswordHash( 8, true );
        }

        $key = time() . ':' . $wp_hasher->HashPassword( $key );

        $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
    }
    // Create new message
    $msg = __('Hello!') . "\r\n\r\n";
    $msg .= sprintf(__('You asked us to reset your password for your account using the email address %s.'), $user_login) . "\r\n\r\n";
    $msg .= __("If this was a mistake, or you didn't ask for a password reset, just ignore this email and nothing will happen.") . "\r\n\r\n";
    $msg .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    $msg .= site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . "\r\n\r\n";
    $msg .= __('Thanks!') . "\r\n";

    return $msg;
}

add_filter('retrieve_password_message', 'replace_retrieve_password_message', 10, 4);

But I have written this just for your understanding of the issue.但我写这个只是为了让你理解这个问题。 I do not recommend it.我不推荐它。

Recommended Approach:推荐方法:

As the other answer also suggests the right way to do this is to just skip all the key creation that your doing manually and use the right function for this ie get_password_reset_key() , so your code with this approach would look like,正如另一个答案也表明正确的方法是跳过您手动执行的所有密钥创建并为此使用正确的 function 即get_password_reset_key() ,因此您使用这种方法的代码看起来像,

// Custom message
function replace_retrieve_password_message($message, $key, $user_login, $user_data) {

    $key = get_password_reset_key( $user_data );

    // Create new message
    $msg = __('Hello!') . "\r\n\r\n";
    $msg .= sprintf(__('You asked us to reset your password for your account using the email address %s.'), $user_login) . "\r\n\r\n";
    $msg .= __("If this was a mistake, or you didn't ask for a password reset, just ignore this email and nothing will happen.") . "\r\n\r\n";
    $msg .= __('To reset your password, visit the following address:') . "\r\n\r\n";
    $msg .= site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . "\r\n\r\n";
    $msg .= __('Thanks!') . "\r\n";

    return $msg;
}

add_filter('retrieve_password_message', 'replace_retrieve_password_message', 10, 4);

As you can see that it is more cleaner.如您所见,它更清洁。 It is also better to use the existing functions where available and applicable.最好在可用且适用的情况下使用现有功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM