【HarmonyOS】云开发-用户自动认证

背景


华为云服务提供了统一认证的云服务,支持手机、邮箱等自定义登录服务,并且提供了免费使用的额度,这样子方便中小企业或者项目快速的开发工作。下面是支持的认证方式:

操作步骤

1.AGC(AppGallery Connect)创建项目

在AGC界面创建自己的云服务项目(详细可看上篇文章【HarmonyOS】端云一体化初始化项目),并开通认证服务,如下图:

启用手机号码和邮箱地址服务:

2.添加项目配置文件

在AGC的项目界面下载agconnect-services.json文件,并添加到本地的项目文件中。

3.添加与云服务相关的第三方库

  • 在项目的终端中,输入 cd entry 进入entry目录
  • 安装SDK
ohpm install @hw-agconnect/hmcore
ohpm install @hw-agconnect/cloud

可以在entry->oh-package.json5文件中可以查看添加的第三方库和对应的版本号,可以看到添加了 @hw-agconnect/hmcore和 @hw-agconnect/cloud两个第三方库。

示例使用手机验证码实现登录功能

验证码的操作示意图

1.搭建初始化界面

import { router } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  //手机号码
  @State TelNumber: string = "";
  //验证码
  @State VerifyNumber: string = "";

  build() {
    Column() {
      TextInput({ placeholder: "请输入手机号" })
        .width("80%")
        .type(InputType.PhoneNumber)
        .height(50)
        .onChange(value => {
          this.TelNumber = value;
        })
      Row() {
        TextInput({ placeholder: "请输入验证码" })
          .width("50%")
          .type(InputType.Number)
          .height(50)
          .onChange(value => {
            this.VerifyNumber = value;
          })
        Button("获取验证码")
          .fontSize(14)
          .layoutWeight(1)
          .margin({ left: 20 })
          .height(50)
      }
      .width("80%")
      .margin({ top: 20, bottom: 20 })

      Button("登录").onClick((event: ClickEvent) => {
        
      })
        .width("80%")
    }
    .height('100%')
    .width('100%')
    .padding(10)
    .backgroundColor($r('app.color.start_window_background'))
    .alignItems(HorizontalAlign.Center)
  }
}

2.云服务认证使用初始化

修改EntryAbility文件代码进行初始化

  • 添加import { initialize } from ‘@hw-agconnect/hmcore’
  • 添加配置的JSON文件路径 :import serciceJson from ‘…/…/resources/rawfile/agconnect-services.json’
  • 在OnCreate方法中添加初始化代码

修改示意图:

整体代码如下:

import { abilityAccessCtrl, AbilityConstant, PermissionRequestResult, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { initialize } from '@hw-agconnect/hmcore'
import serciceJson from '../../resources/rawfile/agconnect-services.json'

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    try {
      initialize(this.context, serciceJson);
    } catch (e) {
      hilog.error(0x0000, 'AGConnectError', JSON.stringify(e));
    }
    let AtManager = abilityAccessCtrl.createAtManager();
    AtManager.requestPermissionsFromUser(this.context, ['ohos.permission.READ_MEDIA', 'ohos.permission.MEDIA_LOCATION'])
      .then((data: PermissionRequestResult) => {
        hilog.info(0x0000, 'testTag', '%{public}s', 'request permissions from user success' + data);
      })
      .catch((err: Object) => {
        hilog.error(0x0000, 'testTag', 'Failed to request permissions from user. Cause: %{public}s',
          JSON.stringify(err) ?? '');
      });
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

发送验证码

输入手机号码后点击获取验证码按钮,然后获取登录的验证码短信。短信截图如下:

完整代码:

import { router } from '@kit.ArkUI';
import cloud from '@hw-agconnect/cloud'
import { Auth, VerifyCodeAction } from '@hw-agconnect/cloud';
import hilog from '@ohos.hilog';
import json from '@ohos.util.json';
import { JSON } from '@kit.ArkTS';

@Entry
@Component
struct Index {
  //手机号码
  @State TelNumber: string = "";
  //验证码
  @State VerifyNumber: string = "";

  build() {
    Column() {
      TextInput({ placeholder: "请输入手机号" })
        .width("80%")
        .type(InputType.PhoneNumber)
        .height(50)
        .onChange(value => {
          this.TelNumber = value;
        })
      Row() {
        TextInput({ placeholder: "请输入验证码" })
          .width("50%")
          .type(InputType.Number)
          .height(50)
          .onChange(value => {
            this.VerifyNumber = value;
          })
        Button("获取验证码")
          .fontSize(14)
          .layoutWeight(1)
          .margin({ left: 20 })
          .height(50)
          .onClick(async () => {
            try {
              await cloud.auth().requestVerifyCode({
                verifyCodeType: {
                  kind: "phone",
                  phoneNumber: this.TelNumber,
                  countryCode: "86"
                },
                action: VerifyCodeAction.REGISTER_LOGIN,
                lang: "zh_CN",
                sendInterval: 60
              })
              hilog.error(0, 'VerifyCode', "Success");
            } catch (e) {
              AlertDialog.show({ title: "错误", message: "验证码发送失败" })
              hilog.error(0, 'VerifyCode', JSON.stringify(e));
            }
          })
      }
      .width("80%")
      .margin({ top: 20, bottom: 20 })

      Button("登录").onClick((event: ClickEvent) => {

      })
        .width("80%")
    }
    .height('100%')
    .width('100%')
    .padding(10)
    .backgroundColor($r('app.color.start_window_background'))
    .alignItems(HorizontalAlign.Center)
  }
}

主要调用requestVerifyCode方法去获取验证码信息,传入VerifyCodeParam类型对象。

VerifyCodeParam的属性解析:

  • verifyCodeType :PhoneVerifyCode对象,主要输入phoneNumber和countryCode对象。
  • action : 枚举值,选择获取验证码的类型
  • lang : 语言
  • sendInterval : 重复发送的时间间隔

根据验证码实现登录功能

实现登录效果

import { router } from '@kit.ArkUI';
import cloud from '@hw-agconnect/cloud'
import { Auth, VerifyCodeAction } from '@hw-agconnect/cloud';
import hilog from '@ohos.hilog';
import json from '@ohos.util.json';
import { JSON } from '@kit.ArkTS';

@Entry
@Component
struct Index {
  //手机号码
  @State TelNumber: string = "";
  //验证码
  @State VerifyNumber: string = "";

  build() {
    Column() {
      TextInput({ placeholder: "请输入手机号" })
        .width("80%")
        .type(InputType.PhoneNumber)
        .height(50)
        .onChange(value => {
          this.TelNumber = value;
        })
      Row() {
        TextInput({ placeholder: "请输入验证码" })
          .width("50%")
          .type(InputType.Number)
          .height(50)
          .onChange(value => {
            this.VerifyNumber = value;
          })
        Button("获取验证码")
          .fontSize(14)
          .layoutWeight(1)
          .margin({ left: 20 })
          .height(50)
          .onClick(async () => {
            try {
              await cloud.auth().requestVerifyCode({
                verifyCodeType: {
                  kind: "phone",
                  phoneNumber: this.TelNumber,
                  countryCode: "86"
                },
                action: VerifyCodeAction.REGISTER_LOGIN,
                lang: "zh_CN",
                sendInterval: 60
              })
              hilog.error(0, 'VerifyCode', "Success");
            } catch (e) {
              AlertDialog.show({ title: "错误", message: "验证码发送失败" })
              hilog.error(0, 'VerifyCode', JSON.stringify(e));
            }
          })
      }
      .width("80%")
      .margin({ top: 20, bottom: 20 })

      Button("登录").onClick(async (event: ClickEvent) => {
        try {
          const result = await cloud.auth().signIn({
            credentialInfo: {
              kind: "phone",
              countryCode: "86",
              phoneNumber: this.TelNumber,
              verifyCode: this.VerifyNumber
            }
          })
          AlertDialog.show({ title: "登录", message: "登录成功!!!" })
        } catch (e) {
          AlertDialog.show({ title: "错误", message: "登录失败" })
          hilog.error(0, 'Login', JSON.stringify(e));
        }
      })
        .width("80%")
    }
    .height('100%')
    .width('100%')
    .padding(10)
    .backgroundColor($r('app.color.start_window_background'))
    .alignItems(HorizontalAlign.Center)
  }
}

主要调用auth的signIn方法,并传入对应的电话号码和验证码。
SignInParam对象

  • credentialInfo: CredentialInfo对象,设置电话号码和前缀,可以选择密码登录或者验证码登录
  • autoCreateUser?: boolean; 设置当没有当前对象存在时,是否需要自动生成用户。

总结

以上示例仅仅对统一认证流程的讲解,其中完整的逻辑判断并没有添加,可以根据自己的需求来添加相应的逻辑判断

  • 26
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baobao熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值