WordPress Rest API 重置用户密码时要求输入原密码的方法
2022-06-17
WordPress Rest API默认只需要用户有权限便可重置用户密码。
对于前后端分离的项目,为了安全,重置密码一般要求用户输入原密码。
基础原理是在更新用户密码前进行“拦截”,额外逻辑判断。
用到的钩子Hook是rest_pre_insert_user,详细用法如下:
<?php
add_filter( 'rest_pre_insert_user', 'pury_custom_rest_pre_insert_user', 10, 2 );
function pury_custom_rest_pre_insert_user( $prepared_user, $request ) {
$user_id = get_current_user_id();
$target_user_id = (int) $prepared_user->ID;
// 如果参数用没有密码字段,直接返回正常流程
if (!isset($prepared_user->user_pass) ) return $prepared_user;
$user = get_user_by( 'id', $target_user_id );
// 创建新用户,单独处理,通常是管理员操作,暂时直接通过,不做额外处理
// 按需添加逻辑判断
if (!$user) {
if (current_user_can('manage_options')) {
$prepared_user->user_pass = $request['password'];
return $prepared_user;
} else {
return new WP_Error(
'no_access',
__( '无权限!' ),
array( 'status' => 400 )
);
}
}
$pwd_c = $request['current_password']; // 旧密码
$pwd_v = $request['new_password']; // 重复新密码
$password = $request['password']; // 新密码
if ($password !== $pwd_v) {
return new WP_Error(
'error args',
__( '两次新密码不一致,请重新输入!' ),
array( 'status' => 400 )
);
}
global $wpdb;
$user_data = $wpdb->get_row($wpdb->prepare(
"SELECT user_pass FROM $wpdb->users WHERE ID=%d", $target_user_id));
$user_pass = $user_data->user_pass;
$check = wp_check_password($pwd_c, $user_pass, $target_user_id);
// 验证旧密码
if (!$check) {
return new WP_Error(
'error args',
__( '旧密码不正确,请重新输入!' ),
array( 'status' => 400 )
);
}
$check = wp_check_password($password, $user_pass, $target_user_id);
if ($check) {
return new WP_Error(
'error args',
__( '新密码不能与旧密码相同,请重新输入!' ),
array( 'status' => 400 )
);
}
// 全部通过,返回正常流程
$prepared_user->user_pass = $password;
return $prepared_user;
}
重置密码需要传入三个参数:原密码(current_password)、新密码(password)和重复新密码(new_password)。其中,参数password必须不变,因为内核会用到,其他两个可自定义。
注释比较详细,注意辨别。
然后,需要在内核主流程中插入错误验证判断,文件位置:
/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
一共有两处:
<?php
$user = $this->prepare_item_for_database( $request );
if ( is_wp_error( $user ) ) {
return $user;
}
(版权归cpury.com所有,转载请注明出处。)