WordPress Rest API 用户重置密码时要求输入旧密码的解决方案

WordPress Rest API默认情况下,重置密码与修改用户其他属性(如昵称等)一样,只要有权限便可操作。

但对于前后端分离的项目,重置密码时有必要让用户输入旧密码,提升安全性。

推荐使用钩子Hookrest_pre_insert_user,在执行更新用户密码前进行额外逻辑判断。

重置密码需要传入三个参数:旧密码(old_password)、新密码(password)和重复新密码(repeat_password)。其中,为避免麻烦,参数password名称必须保持不变,因为内核会用到,其他两个可自定义。

效果如图:

在这里插入图片描述

第一步:应用钩子

主要功能:

  • 验证旧密码正确
  • 验证新密码和重复新密码保持一致
  • 验证新密码与旧密码不一样
<?php

add_filter( 'rest_pre_insert_user', 'szwzjx_custom_rest_pre_insert_user', 10, 2 );

function szwzjx_custom_rest_pre_insert_user( $prepared_user, $request ) {
    // 目标用户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['old_password'];  // 旧密码
    $pwd_v =    $request['repeat_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;
}

第二步:拓展主流程

在内核主流程中插入错误验证判断,文件位置:
/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;
		}

此文件也是钩子rest_pre_insert_user实际应用的地方。

	protected function prepare_item_for_database( $request ) {
		$prepared_user = new stdClass;
		// ....
		return apply_filters( 'rest_pre_insert_user', $prepared_user, $request );
	}

前端调用接口示例:

import axios from 'axios';
import Session from './session';

// 重置自己密码
const reset_password = () => {
	const option = {
		old_password: '123456', // 当前密码
		password: 'hello', // 新密码
		repeat_password: 'hello' // 重复新密码
	};
	const sessionKey = Session.get();
	const headers = { 'Authorization': 'Bearer' + sessionKey };
	const reqUrl = 'wp-json/wp/v2/users/me';
	return axios.post(reqUrl, option, { headers });
}

:对WordPress内核有微调,请谨慎参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值