DEV Community

xuxianlang
xuxianlang

Posted on

HarmonyOS开发云认证密码修改报错(account or verification code is incorrect.)解决方案

HarmonyOS开发云认证密码修改报错(account or verification code is incorrect.)解决方案

问题背景

近期在鸿蒙云认证密码修改功能中,遇到错误代码203818129,提示信息为:

{"code":203818129,"message":"account or verification code is incorrect."}
Enter fullscreen mode Exit fullscreen mode

原问题代码

import cloud, { AuthUser, VerifyCodeAction } from '@hw-agconnect/cloud'
import { promptAction } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
@Component
struct UpdatePassword {
  // 状态变量:接收输入的手机号(字符串类型)
  @State phoneNumber: string = ""
  // 状态变量:接收输入的要修改的密码(字符串类型)
  @State password: string = ""
  // 状态变量:接受输入的确认密码(字符串类型)
  @State repass: string = ""
  // 状态变量:接收输入的验证码(字符串类型)
  @State verifyCode: string = ""
  // 状态变量:设置验证码时间(数值类型)
  @State time: number = 0
  // 状态变量:设置验证码是否已点击的状态(布尔类型)
  @State isClick: boolean = false
  // 状态变量:设置计时器(数值类型)
  @State timer: number = 0

  /**
   * 获取验证码函数
   */
  getVerifyCode() {
    // 调用官方提供的请求验证码方法
    cloud.auth().requestVerifyCode({
      action: VerifyCodeAction.REGISTER_LOGIN,
      lang: "zh_CN",
      sendInterval: 600,
      verifyCodeType: {
        phoneNumber: this.phoneNumber,
        countryCode: '86',
        kind: 'phone'
      }
    }).then((verifyCodeResult => {
      // 设置等待时间60s
      this.time = 60
      // 初始设置已点击状态为true
      this.isClick = true
      // 调用计时器,每隔1000ms运行一次time--,直到time为1,设置已点击状态为false,并且清空定时器
      this.timer = setInterval(() => {
        if (this.time > 1) {
          this.time--
        } else {
          this.isClick = false
          clearInterval(this.timer)
        }
      }, 1000)
      // 验证码发送成功的提示
      promptAction.showToast({ message: `验证码已发送` })
      console.log("====>verifyCodeSuccess:", JSON.stringify(verifyCodeResult))
    })).catch((err: BusinessError) => {
      // 验证码发送失败的提示
      promptAction.showToast({ message: `验证码发送失败,${err.message}` })
      console.log("====>verifyCodeErr:", JSON.stringify(err))
    })
  }

  /**
   * 修改密码
   */
  async updatePass() {
    // 判断用户两次输入的密码是否一致,不一致提示并保持原密码
    if (this.password != this.repass) {
      promptAction.showToast({ message: `两次输入的密码不一致` })
      return
    }
    try {
      // 由于鸿蒙官方的云认证必须先登录才能修改密码,所以需要判断当前用户是否登录
      let user: AuthUser | null = await cloud.auth().getCurrentUser()
      // 如果用户未登录,提示先要登录并且保持原密码不变
      if (!user) {
        promptAction.showToast({ message: `请先登录` })
        return
      }
      // 调用官方修改密码方法
      await user.updatePassword({
        password: this.password,
        providerType: "phone",
        verifyCode: this.verifyCode
      })
      // 修改密码成功提示
      promptAction.showToast({ message: `密码更新成功` })
    } catch (e) {
      // 修改密码失败提示
      promptAction.showToast({ message: `密码更改失败${e.message}` })
      console.log(JSON.stringify(e))
    }
  }

  // UI界面构建
  build() {
    Column({ space: 20 }) {
      Text("修改密码")
        .textAlign(1)
        .width("100%")
        .fontSize(32)
        .fontWeight(800)
      TextInput({ placeholder: "请输入手机号码", text: $$this.phoneNumber })
        .width("100%")
      TextInput({ placeholder: "请输入密码", text: $$this.password })
        .width("100%")
        .type(7)
      TextInput({ placeholder: "请再次输入密码", text: $$this.repass })
        .width("100%")
        .type(7)
      Row({ space: 5 }) {
        TextInput({ placeholder: "手机验证码", text: $$this.verifyCode })
          .layoutWeight(1)
        // 状态判断,如果isClick是true,说明button按钮已点击,字体变成重新获取验证码,并且将倒计时的时间显示,设置不可点击
        Button(this.isClick ? `重新获取验证码${this.time}` : "获取验证码").onClick(() => {
          this.getVerifyCode()
        })
          .enabled(!this.isClick)
          .backgroundColor("#f00")
      }
      .width("100%")

      Button("修改密码").onClick(() => {
        this.updatePass()
      })
        .width("100%")
    }
    .justifyContent(FlexAlign.Center)
    .padding(20)
    .height('100%')
    .width('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

解决方案

错误原因分析

account or verification code is incorrect.翻译过来就是用户或验证码不正确,但是验证码就是在这个登录用户下点击的,用户名就不可能错误,验证码也是直接发送到手机的,核对也是没有任何问题的,那是什么原因呢?自己核对代码及华为官方文档点击登录认证,点击手机,在最后重置密码中代码是这样的

auth.requestVerifyCode({
action: VerifyCodeAction.RESET_PASSWORD,
lang: 'zh_CN',
sendInterval: 60,
verifyCodeType: {
 phoneNumber: '138********',
 countryCode: '86',
 kind: "phone",
}
}).then(verifyCodeResult => {
// 验证码申请成功
}).catch(error => {
// 验证码申请失败
});

原来是VerifyCodeAction枚举值误用:

  • REGISTER_LOGIN:用于注册/登录场景
  • RESET_PASSWORD:用于密码重置场景

修复步骤

  1. 定位到验证码请求函数
  2. 修改action参数值为VerifyCodeAction.RESET_PASSWORD

修复后代码

import cloud, { AuthUser, VerifyCodeAction } from '@hw-agconnect/cloud'
import { promptAction } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
@Component
struct UpdatePassword {
  // 状态变量:接收输入的手机号(字符串类型)
  @State phoneNumber: string = ""
  // 状态变量:接收输入的要修改的密码(字符串类型)
  @State password: string = ""
  // 状态变量:接受输入的确认密码(字符串类型)
  @State repass: string = ""
  // 状态变量:接收输入的验证码(字符串类型)
  @State verifyCode: string = ""
  // 状态变量:设置验证码时间(数值类型)
  @State time: number = 0
  // 状态变量:设置验证码是否已点击的状态(布尔类型)
  @State isClick: boolean = false
  // 状态变量:设置计时器(数值类型)
  @State timer: number = 0

  /**
   * 获取验证码函数
   */
  getVerifyCode() {
    // 调用官方提供的请求验证码方法
    cloud.auth().requestVerifyCode({
      action: VerifyCodeAction.RESET_PASSWORD,
      lang: "zh_CN",
      sendInterval: 600,
      verifyCodeType: {
        phoneNumber: this.phoneNumber,
        countryCode: '86',
        kind: 'phone'
      }
    }).then((verifyCodeResult => {
      // 设置等待时间60s
      this.time = 60
      // 初始设置已点击状态为true
      this.isClick = true
      // 调用计时器,每隔1000ms运行一次time--,直到time为1,设置已点击状态为false,并且清空定时器
      this.timer = setInterval(() => {
        if (this.time > 1) {
          this.time--
        } else {
          this.isClick = false
          clearInterval(this.timer)
        }
      }, 1000)
      // 验证码发送成功的提示
      promptAction.showToast({ message: `验证码已发送` })
      console.log("====>verifyCodeSuccess:", JSON.stringify(verifyCodeResult))
    })).catch((err: BusinessError) => {
      // 验证码发送失败的提示
      promptAction.showToast({ message: `验证码发送失败,${err.message}` })
      console.log("====>verifyCodeErr:", JSON.stringify(err))
    })
  }

  /**
   * 修改密码
   */
  async updatePass() {
    // 判断用户两次输入的密码是否一致,不一致提示并保持原密码
    if (this.password != this.repass) {
      promptAction.showToast({ message: `两次输入的密码不一致` })
      return
    }
    try {
      // 由于鸿蒙官方的云认证必须先登录才能修改密码,所以需要判断当前用户是否登录
      let user: AuthUser | null = await cloud.auth().getCurrentUser()
      // 如果用户未登录,提示先要登录并且保持原密码不变
      if (!user) {
        promptAction.showToast({ message: `请先登录` })
        return
      }
      // 调用官方修改密码方法
      await user.updatePassword({
        password: this.password,
        providerType: "phone",
        verifyCode: this.verifyCode
      })
      // 修改密码成功提示
      promptAction.showToast({ message: `密码更新成功` })
    } catch (e) {
      // 修改密码失败提示
      promptAction.showToast({ message: `密码更改失败${e.message}` })
      console.log(JSON.stringify(e))
    }
  }

  // UI界面构建
  build() {
    Column({ space: 20 }) {
      Text("修改密码")
        .textAlign(1)
        .width("100%")
        .fontSize(32)
        .fontWeight(800)
      TextInput({ placeholder: "请输入手机号码", text: $$this.phoneNumber })
        .width("100%")
      TextInput({ placeholder: "请输入密码", text: $$this.password })
        .width("100%")
        .type(7)
      TextInput({ placeholder: "请再次输入密码", text: $$this.repass })
        .width("100%")
        .type(7)
      Row({ space: 5 }) {
        TextInput({ placeholder: "手机验证码", text: $$this.verifyCode })
          .layoutWeight(1)
        // 状态判断,如果isClick是true,说明button按钮已点击,字体变成重新获取验证码,并且将倒计时的时间显示,设置不可点击
        Button(this.isClick ? `重新获取验证码${this.time}` : "获取验证码").onClick(() => {
          this.getVerifyCode()
        })
          .enabled(!this.isClick)
          .backgroundColor("#f00")
      }
      .width("100%")

      Button("修改密码").onClick(() => {
        this.updatePass()
      })
        .width("100%")
    }
    .justifyContent(FlexAlign.Center)
    .padding(20)
    .height('100%')
    .width('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

修改后密码重置不成功的问题就解决了!

Top comments (0)