check_password_reset_key()
云策文档标注
概述
check_password_reset_key() 函数用于根据密码重置密钥和用户登录名检索用户行,验证密钥的有效性和过期状态。它返回 WP_User 对象或 WP_Error 对象,并支持过滤钩子以自定义行为。
关键要点
- 函数接受两个必需参数:$key(密码重置密钥)和 $login(用户登录名),均需为非空字符串。
- 返回类型为 WP_User 或 WP_Error:成功时返回 WP_User 对象,无效或过期密钥时返回 WP_Error 对象。
- 密钥过期机制:通过 user_activation_key 字段处理,旧式明文密钥不再接受,但提供不同的 WP_Error 代码以改善用户反馈。
- 支持过滤钩子:password_reset_expiration 用于自定义密钥过期时间,password_reset_key_expired 用于处理旧式或过期密钥的返回值。
- 内部使用 wp_verify_fast_hash() 验证密钥哈希,get_user_by() 检索用户信息。
代码示例
function check_password_reset_key(
#[SensitiveParameter]
$key,
$login
) {
$key = preg_replace( '/[^a-z0-9]/i', '', $key );
if ( empty( $key ) || ! is_string( $key ) ) {
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
if ( empty( $login ) || ! is_string( $login ) ) {
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
$user = get_user_by( 'login', $login );
if ( ! $user ) {
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
$expiration_duration = apply_filters( 'password_reset_expiration', DAY_IN_SECONDS );
if ( str_contains( $user->user_activation_key, ':' ) ) {
list( $pass_request_time, $pass_key ) = explode( ':', $user->user_activation_key, 2 );
$expiration_time = $pass_request_time + $expiration_duration;
} else {
$pass_key = $user->user_activation_key;
$expiration_time = false;
}
if ( ! $pass_key ) {
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
$hash_is_correct = wp_verify_fast_hash( $key, $pass_key );
if ( $hash_is_correct && $expiration_time && time() < $expiration_time ) {
return $user;
} elseif ( $hash_is_correct && $expiration_time && time() > $expiration_time ) {
$return = new WP_Error( 'expired_key', __( 'Invalid key.' ) );
$user_id = $user->ID;
return apply_filters( 'password_reset_key_expired', $return, $user_id );
} elseif ( ! $hash_is_correct && wp_check_fast_hash( $user->user_activation_key, $key ) || ( $hash_is_correct && ! $expiration_time ) ) {
$return = new WP_Error( 'expired_key', __( 'Invalid key.' ) );
$user_id = $user->ID;
return apply_filters( 'password_reset_key_expired', $return, $user_id );
}
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}注意事项
- 密钥处理:函数会清理 $key 参数,移除非字母数字字符,确保安全验证。
- 错误处理:所有无效情况(如空参数、用户不存在、密钥不匹配)均返回 WP_Error 对象,代码为 'invalid_key' 或 'expired_key'。
- 兼容性:自 3.1.0 版本引入,支持旧式密钥处理,但推荐使用哈希机制以提高安全性。
原文内容
Retrieves a user row based on password reset key and login.
Description
A key is considered ‘expired’ if it exactly matches the value of the user_activation_key field, rather than being matched after going through the hashing process. This field is now hashed; old values are no longer accepted but have a different WP_Error code so good user feedback can be provided.
Parameters
$keystringrequired-
The password reset key.
$loginstringrequired-
The user login.
Source
function check_password_reset_key(
#[SensitiveParameter]
$key,
$login
) {
$key = preg_replace( '/[^a-z0-9]/i', '', $key );
if ( empty( $key ) || ! is_string( $key ) ) {
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
if ( empty( $login ) || ! is_string( $login ) ) {
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
$user = get_user_by( 'login', $login );
if ( ! $user ) {
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
/**
* Filters the expiration time of password reset keys.
*
* @since 4.3.0
*
* @param int $expiration The expiration time in seconds.
*/
$expiration_duration = apply_filters( 'password_reset_expiration', DAY_IN_SECONDS );
if ( str_contains( $user->user_activation_key, ':' ) ) {
list( $pass_request_time, $pass_key ) = explode( ':', $user->user_activation_key, 2 );
$expiration_time = $pass_request_time + $expiration_duration;
} else {
$pass_key = $user->user_activation_key;
$expiration_time = false;
}
if ( ! $pass_key ) {
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
$hash_is_correct = wp_verify_fast_hash( $key, $pass_key );
if ( $hash_is_correct && $expiration_time && time() < $expiration_time ) {
return $user;
} elseif ( $hash_is_correct && $expiration_time ) {
// Key has an expiration time that's passed.
return new WP_Error( 'expired_key', __( 'Invalid key.' ) );
}
if ( hash_equals( $user->user_activation_key, $key ) || ( $hash_is_correct && ! $expiration_time ) ) {
$return = new WP_Error( 'expired_key', __( 'Invalid key.' ) );
$user_id = $user->ID;
/**
* Filters the return value of check_password_reset_key() when an
* old-style key or an expired key is used.
*
* @since 3.7.0 Previously plain-text keys were stored in the database.
* @since 4.3.0 Previously key hashes were stored without an expiration time.
*
* @param WP_Error $return A WP_Error object denoting an expired key.
* Return a WP_User object to validate the key.
* @param int $user_id The matched user ID.
*/
return apply_filters( 'password_reset_key_expired', $return, $user_id );
}
return new WP_Error( 'invalid_key', __( 'Invalid key.' ) );
}
Hooks
- apply_filters( ‘password_reset_expiration’, int $expiration )
-
Filters the expiration time of password reset keys.
- apply_filters( ‘password_reset_key_expired’, WP_Error $return, int $user_id )
-
Filters the return value of check_password_reset_key() when an old-style key or an expired key is used.
Changelog
| Version | Description |
|---|---|
| 3.1.0 | Introduced. |