【最新鸿蒙应用开发】——手机验证码登录业务(axios)

如何完成验证码登录业务?

封装axios请求,通过登录页发送请求,获取验证码后进行判断登录成功。

效果图:

一、解压封装好的axios资源包并导入使用

鸿蒙编译器里面使用axios需要进行安装(详情看完之前文章),在命令控制台输入:

ohpm install @ohos/axios

安装完成后将我封装好的包负责粘贴到项目中ets目录下即可:

二、登录页面ets:

import {
  BizType,
  LoginInfoResponse,
  postCodeGraphicCheckAPI,
  postCodeSmsSendAPI,
  postUserLoginVerifyCodeAPI
} from '../../api'
import { BASE_URL, LOGIN_INFO,  } from '../../common/constants'
import { promptAction, router } from '@kit.ArkUI'
PersistentStorage.persistProp<LoginInfoResponse>(LOGIN_INFO, {})

@Entry
@Component
struct UserLoginPage {
  // 用户信息持久化
  @StorageLink(LOGIN_INFO) loginInfo: LoginInfoResponse = {}
  // 手机号
  @State phoneNumber: string = '131234567894'
  // 短信验证码
  @State verifyCode: string = ''
  // 显示半模态转场结构
  @State isShowSheet: boolean = false
  // 用于更新验证码的时间戳
  @State timestamp: number = Date.now()
  // 图形验证码
  @State graphicCode: string = ''
  // 倒计时数值
  @State count: number = 0
  // 倒计时定时器
  private intervalID: number = -1

  // 校验图形验证码
  async onSubmitGraphic() {
    try {
      await postCodeGraphicCheckAPI({
        bizType: BizType.PhoneLogin, // 业务类型,1:手机号短信验证码登录
        phone: this.phoneNumber, // 手机号
        verifyCode: this.graphicCode // 图形验证码
      })
      // 图形验证码正确,发送短信验证码
      this.onSendSmsCode()
      // 关闭模态层
      this.isShowSheet = false
    } catch (error) {
      // 刷新验证码
      this.timestamp = Date.now()
    }
  }

  // 发送短信验证码
  async onSendSmsCode() {
    // 发送验证码
    await postCodeSmsSendAPI({
      bizType: BizType.PhoneLogin,
      phone: this.phoneNumber,
    })
    // 用户提醒
    promptAction.showToast({ message: '短信发送到手机上,请注意查收' })
    // 界面更新倒计时
    this.startCountDown()
  }

  // 开始倒计时
  startCountDown() {
    // 初始化倒计时秒数
    this.count = 60
    // 关闭旧的定时器
    clearInterval(this.intervalID)
    // 开启定时器
    this.intervalID = setInterval(() => {
      this.count--
      if (this.count <= 0) {
        clearInterval(this.intervalID)
      }
    }, 1000)
  }

  // 页面销毁,停止倒计时,释放资源
  aboutToDisappear() {
    clearInterval(this.intervalID)
  }

  // 登录提交
  async onLoginSubmit() {
    const res = await postUserLoginVerifyCodeAPI({
      phone: this.phoneNumber,
      verifyCode: this.verifyCode
    })
    //
    promptAction.showToast({ message: '登录成功' })
    // 更新持久化存储的信息
    this.loginInfo = res.data.result
    // 返回上一页
    router.back()
  }

  // 半模态转场
  @Builder
  SheetBuilder() {
    Column() {
      Text('图形验证码')
        .fontSize(16)
        .fontColor($r('app.color.font'))
        .margin({ top: 20, bottom: 50 })

      Column({ space: 20 }) {
        Row({ space: 10 }) {
          TextInput({ placeholder: '图形验证码' })
            .fontSize(14)
            .height(42)
            .layoutWeight(1)
            .maxLength(4)
            .onChange((value) => {
              this.graphicCode = value
            })
            .onSubmit(() => {
              // TODO:提交图形验证码
              this.onSubmitGraphic()
            })
          Image(`${BASE_URL}/code/graphic?phone=${this.phoneNumber}&bizType=${1}&timestamp=${this.timestamp}`)
            .width(108)
            .height(42)
            .objectFit(ImageFit.Contain)
            .onClick(() => {
              this.timestamp = Date.now()
            })
        }

        Button("提交")
          .height(42)
          .backgroundColor($r('app.color.brand'))
          .width('100%')
          .enabled(this.graphicCode.length > 0)
          .onClick(() => {
            // TODO:提交图形验证码
            this.onSubmitGraphic()
          })
      }
    }
    .padding({ left: 30, right: 30 })
    .width('100%')
    .height('100%')
  }

  build() {
    Navigation() {
      Column() {
        Row({ space: 30 }) {
          Text('验证码登录')
            .fontSize(22)
            .fontWeight(500)
            .fontColor($r('app.color.font'))
        }
        .width('100%')

        Column({ space: 10 }) {
          TextInput({ placeholder: '请输入手机号', text: this.phoneNumber })
            .type(InputType.PhoneNumber)
            .maxLength(12)
            .fontSize(14)
            .height(50)
            .backgroundColor(Color.Transparent)
            .border({ width: { bottom: 1 }, color: $r('app.color.border'), radius: 0 })
            .padding(0)
            .onChange((value) => {
              this.phoneNumber = value
            })

          Stack({ alignContent: Alignment.End }) {
            TextInput({ placeholder: '请输入验证码', text: this.verifyCode })
              .type(InputType.Number)
              .maxLength(6)
              .fontSize(14)
              .height(50)
              .backgroundColor(Color.Transparent)
              .border({ width: { bottom: 1 }, color: $r('app.color.border'), radius: 0 })
              .padding(0)
              .onChange((value) => {
                this.verifyCode = value
              })
            if (this.count > 0) {
              Text(this.count + '秒后重发')
                .fontSize(14)
                .fontColor($r('app.color.font_sub'))
            } else {
              Text('获取验证码')
                .fontSize(14)
                .fontColor($r('app.color.brand'))
                .enabled(this.phoneNumber.length > 0)
                .onClick(() => {
                  this.isShowSheet = true
                })
            }
          }
        }
        .margin({ top: 40, bottom: 40 })

        Column({ space: 20 }) {
          Button('登录')
            .backgroundColor($r('app.color.brand'))
            .height(42)
            .width('100%')
            .enabled(this.phoneNumber.length > 0 && this.verifyCode.length > 0)
            .onClick(() => {
              // TODO:登录表单提交
              this.onLoginSubmit()
            })

        }
      }
      .padding({ left: 30, right: 30, top: 30 })
      .width('100%')
      .height('100%')
    }
    .titleMode(NavigationTitleMode.Mini)
    .mode(NavigationMode.Stack)
    .bindSheet($$this.isShowSheet, this.SheetBuilder(), {
      // 半模态转场,屏幕高度一半,无法修改关闭图标样式
      detents: [SheetSize.MEDIUM],
      backgroundColor: $r('app.color.white')
    })
  }
}

查验证码:

在线WebSocket地址:wss://guardian-api.itheima.net/verifyCode

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Hutool的验证码工具类来生成验证码,并将其展示在登录页面上,然后使用axios将用户输入的账号、密码和验证码发送给后端进行验证。 以下是一个示例代码: 前端部分: ```html <!-- 展示验证码 --> <img id="captchaImg" src="/captcha"> <!-- 账号输入框 --> <input type="text" id="username"> <!-- 密码输入框 --> <input type="password" id="password"> <!-- 验证码输入框 --> <input type="text" id="captchaInput"> <!-- 登录按钮 --> <button onclick="login()">登录</button> ``` ```javascript function login() { const username = document.getElementById('username').value; const password = document.getElementById('password').value; const captcha = document.getElementById('captchaInput').value; axios.post('/login', { username, password, captcha }).then(response => { if (response.data.success) { // 登录成功 } else { // 登录失败 } }); } ``` 后端部分: ```java // 生成验证码 String captcha = CaptchaUtil.createLineCaptcha(200, 100, 4, 150).getCode(); // 将验证码存储到session中 request.getSession().setAttribute("captcha", captcha); // 验证登录信息 String username = request.getParameter("username"); String password = request.getParameter("password"); String inputCaptcha = request.getParameter("captcha"); String sessionCaptcha = (String) request.getSession().getAttribute("captcha"); boolean success = inputCaptcha.equalsIgnoreCase(sessionCaptcha) && "admin".equals(username) && "123456".equals(password); Map<String, Object> resultMap = new HashMap<>(); resultMap.put("success", success); // 将验证结果返回给前端 response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(JSON.toJSONString(resultMap)); ``` 在上面的示例代码中,前端展示了一个验证码图片,并提供了账号、密码和验证码的输入框以及一个登录按钮。当用户点击登录按钮时,通过axios将用户输入的账号、密码和验证码发送到后端进行验证。后端使用Hutool的验证码工具类生成验证码,并将其存储到session中。当用户输入账号、密码和验证码并点击登录按钮时,后端将用户输入的验证码与session中的验证码进行比较,判断验证码是否正确,同时还判断账号密码是否正确。最后,后端将验证结果返回给前端。如果登录验证成功,可以将用户的相关信息存储到session中,以便后续的操作使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值