一、介绍
基于鸿蒙Next模拟账号一键登录,免去账号注册环节
二、场景需求
1. 用户场景
新用户: 需要快速注册并登录,以体验华为的服务。
老用户: 希望快速登录,不用每次输入用户名和密码。
2. 界面设计
Logo和标题: 页面顶部展示华为的Logo及"一键登录"或"华为账号登录"的标题。
3. 功能需求:短信/邮箱验证码:
4. 安全性
二次验证: 可选启用二次验证,如在高风险环境下(新设备登录等),要求用户通过邮件或短信进行确认。
5. 适应性
响应式设计: 确保在不同设备(手机、平板、电脑)上的良好展示。
多语言支持: 提供多种语言选项,方便不同地区用户使用。
6. 用户反馈
操作反馈: 无论是按钮点击还是输入错误,都需要及时反馈用户操作状态。
常见问题解答链接: 用户如果在登录时遇到问题,可以快速找到帮助。

三、业务步骤
第一步:点击“一键登录”,获取登录信息
第二步:拉起授权弹窗
第三步:获取授权,获取用户信息
第四步:展示用户信息,显示功能选项
四、效果展示

模拟登录页,华为账号一键登录 _Image

五:代码展示:

import { authentication } from '@kit.AccountKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';

//自定义
import { Mine_SystemItem_Type,CommonConstants } from "../common/CommonConstant"

@Entry
@Component
struct Index06 {
  @State tabMineItem:Mine_SystemItem_Type[] = CommonConstants.MINE_SYSTEM_ITEM_LIST
  @State isLogin: boolean = false
  @State userImg: string|Resource|undefined = $r("app.media.app_icon") // 登录头像
  @State userName: string|undefined = '昵称001' // 用户昵称
  @State btnTitle: string = '华为账号一键登录' // 用户昵称

  getHuaWeiAccount(){
    // 创建授权请求,并设置参数
    let authRequest = new authentication.HuaweiIDProvider().createAuthorizationWithHuaweiIDRequest();
    // 获取头像昵称需要传如下scope
    authRequest.scopes = ['profile','phone'];
    // 若开发者需要进行服务端开发,则需传如下permission获取authorizationCode
    authRequest.permissions = ['serviceauthcode'];
    // 用户是否需要登录授权,该值为true且用户未登录或未授权时,会拉起用户登录或授权页面
    authRequest.forceAuthorization = true;
    // 用于防跨站点请求伪造。
    authRequest.state = util.generateRandomUUID();
    // 执行授权请求
    try {
      let controller = new authentication.AuthenticationController(getContext(this));
      controller.executeRequest(authRequest).then((data) => {
        let authorizationWithHuaweiIDResponse = data as authentication.AuthorizationWithHuaweiIDResponse;
        let state = authorizationWithHuaweiIDResponse.state;
        if (state != undefined && authRequest.state != state) {
          hilog.error(0x0000, 'testTag', `Failed to authorize. The state is different, response state: ${state}`);
          return;
        }
        hilog.info(0x0000, 'testTag', 'Succeeded in authentication: %{public}s',
          JSON.stringify(authorizationWithHuaweiIDResponse));
        this.isLogin = !this.isLogin
        this.btnTitle = '退出'
        this.userImg = authorizationWithHuaweiIDResponse.data!.avatarUri;
        this.userName = authorizationWithHuaweiIDResponse.data!.nickName;

      }).catch((err: BusinessError) => {
        this.dealAllError(err);
      });
    } catch (error) {
      this.dealAllError(error);
    }
  }
  // 错误处理
  dealAllError(error: BusinessError): void {
    hilog.error(0x0000, 'testTag', `Failed to auth. Code: ${error.code}, message: ${error.message}`);
  }

  build() {
      Column() {
        Column() {
          //头像
          Column() {
            Image(this.userImg)
              .objectFit(ImageFit.Cover)
              .height(72)
              .width(72)
              .borderRadius(36)
            Row().height(20)

            Text(this.userName).fontSize(16)

          }
          .width('90%')
          .borderRadius(12)
          .alignItems(HorizontalAlign.Center)
          .justifyContent(FlexAlign.Center)
          .backgroundColor(0xFFFFFF)
          .shadow({
            radius: 10,
            color: "#dddddd",
            offsetX: 6,
            offsetY: 6
          })
          .margin({ top: 15, bottom: 10 })
          .padding({ top: 30, bottom: 30 })
        }
        .justifyContent(FlexAlign.Start)
        .alignItems(HorizontalAlign.Center)

        Button(this.btnTitle)
          .width('70%')
          .height(30)
          .onClick(()=>{
            this.getHuaWeiAccount()
            // this.isLogin = !this.isLogin
            // this.btnTitle = '退出'
          })
          .margin({ top:10,bottom:20 })

        if (this.isLogin){
        Column(){
          //功能选项
          ForEach(this.tabMineItem,(item:Mine_SystemItem_Type,index:number)=>{
            Row(){
              Text(item.itemTitle).fontSize(16).fontColor(0x161616)
              Blank()
              Image($r("app.media.ic_right_back_greyWhite")).width(24).height(24)
            }.width('100%')
            .height(48)
            .padding({left:15,right:10})
            .stateStyles({
              normal:{.backgroundColor(0xFFFFFF)},
              pressed:{.backgroundColor(0xEFEFEF)}
            })
          },(item:string)=>item)
          Row(){
            Text('隐私声明').fontSize(16).fontColor(0x161616)
            Blank()
            Image($r("app.media.ic_right_back_greyWhite")).width(24).height(24)
          }.width('100%')
          .height(48)
          .padding({left:15,right:10})
          .stateStyles({
            normal:{.backgroundColor(0xFFFFFF)},
            pressed:{.backgroundColor(0xEFEFEF)}
          })

        }.width('90%')
        .justifyContent(FlexAlign.Start)
        .alignItems(HorizontalAlign.Center)
        .backgroundColor(0xFFFFFF)
        .shadow({radius:10,color:"#dddddd",offsetX:6,offsetY:6})
        .padding({top:10,bottom:10})
        .borderRadius(12)
        }

      }.width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Start)
    .backgroundColor(0xEEEEEE)

  }

}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.