)
系列文章目录HarmonyOS Next 系列之省市区弹窗选择器实现一HarmonyOS Next 系列之验证码输入组件实现二HarmonyOS Next 系列之底部标签栏TabBar实现三HarmonyOS Next 系列之HTTP请求封装和Token持久化存储四HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现五HarmonyOS Next 系列之可移动悬浮按钮实现六HarmonyOS Next 系列之沉浸式状态实现的多种方式七HarmonyOS Next系列之Echarts图表组件折线图、柱状图、饼图等)实现八HarmonyOS Next系列之地图组件Map Kit使用九HarmonyOS Next系列之半圆环进度条实现十HarmonyOS Next 系列之列表下拉刷新和触底加载更多数据实现十一HarmonyOS Next系列之实现一个左右露出中间大两边小带缩放动画的轮播图十二HarmonyOS Next系列之水波纹动画特效实现十三HarmonyOS Next系列之华为账号一键登录功能实现十四系列文章目录2【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器上【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器下【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇上【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇下【鸿蒙】HarmonyOS Next 组件或页面之间的所有通信传参方法总结文章目录系列文章目录系列文章目录2前言一、开发前准备1、配置Client ID2、配置scope权限二、功能约束三、页面设计规范四、组件和API讲解1、一键登录按钮组件LoginWithHuaweiIDButton2、修改用户协议状态3、获取用户匿名手机号4、一键登录错误回调处理五、完整代码前言华为账号一键登录是指使用华为账号进行快捷登录的功能。通过一键登录用户可以通过华为账号直接登录到指定的应用无需输入繁琐的账号和密码。一键登录可以提供更便捷、快速、安全的登录方式减少用户的登录烦恼和输入错误。 本文将以代码示例讲解鸿蒙next华为账号一键登录客户端实现过程和页面设计规范。一、开发前准备1、配置Client ID登录AppGallery Connect平台获取在“项目设置 常规 应用”区域获取“OAuth 2.0客户端ID凭据”处的Client ID。在工程中entry模块的module.json5文件中新增metadata配置name为client_idvalue为上一步获取的Client ID的值2、配置scope权限篇幅较长直接看官方教程 开启华为账号服务权限教程二、功能约束1华为账号一键登录服务当前仅限中国大陆用户可用。2后端服务器必须部署在中国大陆境内。3用户必须同意《华为账号用户认证协议》方可登录同时可查看协议详细说明。《华为账号用户认证协议》链接https://privacy.consumer.huawei.com/legal/id/authentication-terms.htm?codeCNlanguagezh-CN系统深色模式下跳转到https://privacy.consumer.huawei.com/legal/id/authentication-terms.htm?codeCNlanguagezh-CNbgmodeblack。三、页面设计规范页面设计不规范将影响审核通过尽量按官方要求来设计页面设计可以参考上图官方示例登录页1首次登录必须要显示用户匿名手机号1首次登录必须要显示“华为账号绑定号码”固定文字2必须要显示《华为账号用户认证协议》点击可以跳到内页查看协议详情。3必须要显示华为账号一键登录按钮4可选择显示应用logo或头像5可选择显示其他登录方式入口6可选择增加显示其他协议比如用户协议、隐私协议等四、组件和API讲解客户端实现一键登录的核心提炼就是通过点击一键登录按钮将回调获取的Authorization Code数据传给服务器后端即可。服务器通过调用获取用户级凭证接口和获取用户信息接口获取用户完整手机号和UnionID、OpenID完成用户关联1、一键登录按钮组件LoginWithHuaweiIDButton引用方式import{LoginWithHuaweiIDButton,loginComponentManager}fromkit.AccountKit;参数说明params为组件参数可以对组件样式进行设置参考params官方文档controller为控制器可以设置用户协议状态setAgreementStatus、一键登录结果事件回调onClickLoginWithHuaweiIDButton等操作参考controller官方文档示例import{loginComponentManager,LoginWithHuaweiIDButton}fromkit.AccountKitEntry Component struct Demo{// 构造LoginWithHuaweiIDButton组件的控制器controller:loginComponentManager.LoginWithHuaweiIDButtonControllernewloginComponentManager.LoginWithHuaweiIDButtonController()/** * 当应用使用自定义的登录页时如果用户未同意协议需要设置协议状态为NOT_ACCEPTED当用户同意协议后再设置 * 协议状态为ACCEPTED才可以使用华为账号一键登录功能 */.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED)//执行一键登录回调.onClickLoginWithHuaweiIDButton((error:BusinessError,response:loginComponentManager.HuaweiIDCredential){if(error){this.dealAllError(error);return;}if(response){// 获取到Authorization CodeconstauthorizationCoderesponse.authorizationCode;//底下逻辑把code通过接口发送个后端实现登录}})// 错误处理dealAllError(error:BusinessError):void{}build(){//一键登录按钮LoginWithHuaweiIDButton({controller:this.controller})}}2、修改用户协议状态用户协议状态必须设置已同意《华为账号用户认证协议》才能正常执行一键登录功能否则返回错误信息可通过controller.setAgreementStatus(status:AgreementStatus) 设置实际开发中初始化控制器默认设置未同意状态等待用户勾选后再改变为已同意。AgreementStatus枚举值import{loginComponentManager}fromkit.AccountKit//已同意controller.setAgreementStatus(loginComponentManager.AgreementStatus.ACCEPTED)//未同意controller.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED)3、获取用户匿名手机号asyncgetAnonymousPhone(){//匿名手机号letanonymousPhone:string// 创建授权请求并设置参数constauthRequestnewauthentication.HuaweiIDProvider().createAuthorizationWithHuaweiIDRequest();// 获取匿名手机号需传quickLoginAnonymousPhone这个scope传参之前需要先申请“华为账号一键登录”权限authRequest.scopes[quickLoginAnonymousPhone];// 用于防跨站点请求伪造authRequest.stateutil.generateRandomUUID();// 一键登录场景该参数必须设置为falseauthRequest.forceAuthorizationfalse;constcontrollernewauthentication.AuthenticationController();try{letresponse:authentication.AuthorizationWithHuaweiIDResponseawaitcontroller.executeRequest(authRequest)anonymousPhoneresponse.data?.extraInfo?.quickLoginAnonymousPhoneasstring;}catch(error){}returnanonymousPhone}4、一键登录错误回调处理错误回调是BusinessError类型错误码枚举值定义如下enumErrorCode{// 账号未登录ERROR_CODE_LOGIN_OUT1001502001,// 该账号不支持一键登录如儿童账号、海外账号ERROR_CODE_NOT_SUPPORTED1001500003,// 网络错误ERROR_CODE_NETWORK_ERROR1001502005,// 用户未同意用户协议ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED1005300001,// 参数错误ERROR_CODE_PARAMETER_ERROR401}处理逻辑// 错误处理dealAllError(error:BusinessError):void{if(error.codeErrorCode.ERROR_CODE_NETWORK_ERROR){AlertDialog.show({message:网络未连接请检查网络设置。,offset:{dx:0,dy:-12},alignment:DialogAlignment.Bottom,autoCancel:false,confirm:{value:知道了,action:(){}}});}elseif(error.codeErrorCode.ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED){// 未同意协议this.showToast(请阅读并同意协议);}elseif(error.codeErrorCode.ERROR_CODE_LOGIN_OUT){// 华为账号未登录提示this.showToast(华为账号未登录请先登录);}elseif(error.codeErrorCode.ERROR_CODE_NOT_SUPPORTED){// 不支持该scopes或permissions提示this.showToast(该scopes或permissions不支持);}elseif(error.codeErrorCode.ERROR_CODE_PARAMETER_ERROR){// 参数错误提示this.showToast(参数错误);}else{// 其他提示系统或服务异常this.showToast(服务或网络异常请稍后重试);}}// Toast提示showToast(resource:string){try{promptAction.showToast({message:resource,duration:2000});}catch(error){}}五、完整代码实现如下图所示效果QuickLoginDemo.ets登录页import{authentication,loginComponentManager,LoginWithHuaweiIDButton}fromkit.AccountKitimport{promptAction,router}fromkit.ArkUI;import{BusinessError}fromkit.BasicServicesKit;import{util}fromkit.ArkTS;Entry Component struct QuickLoginDemo{//是否同意隐私协议State isAgree:booleanfalse//匿名手机号State phone:string// 构造LoginWithHuaweiIDButton组件的控制器controller:loginComponentManager.LoginWithHuaweiIDButtonControllernewloginComponentManager.LoginWithHuaweiIDButtonController()/** * 当应用使用自定义的登录页时如果用户未同意协议需要设置协议状态为NOT_ACCEPTED当用户同意协议后再设置 * 协议状态为ACCEPTED才可以使用华为账号一键登录功能 */.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED).onClickLoginWithHuaweiIDButton((error:BusinessError,response:loginComponentManager.HuaweiIDCredential){if(error){this.dealAllError(error);return;}if(response){// 获取到Authorization CodeconstauthorizationCoderesponse.authorizationCode;console.log(authorizationCode.toString(),code)//底下写接口请求登录逻辑code传给服务器//模拟接口setTimeout((){this.showToast(登录成功)},2000)}});// 错误处理dealAllError(error:BusinessError):void{if(error.codeErrorCode.ERROR_CODE_NETWORK_ERROR){AlertDialog.show({message:网络未连接请检查网络设置。,offset:{dx:0,dy:-12},alignment:DialogAlignment.Bottom,autoCancel:false,confirm:{value:知道了,action:(){}}});}elseif(error.codeErrorCode.ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED){// 未同意协议this.showToast(请阅读并同意协议);}elseif(error.codeErrorCode.ERROR_CODE_LOGIN_OUT){// 华为账号未登录提示this.showToast(华为账号未登录请先登录);}elseif(error.codeErrorCode.ERROR_CODE_NOT_SUPPORTED){// 不支持该scopes或permissions提示this.showToast(该scopes或permissions不支持);}elseif(error.codeErrorCode.ERROR_CODE_PARAMETER_ERROR){// 参数错误提示this.showToast(参数错误);}else{// 其他提示系统或服务异常this.showToast(服务或网络异常请稍后重试);}}// Toast提示showToast(resource:string){try{promptAction.showToast({message:resource,duration:2000});}catch(error){}}//获取匿名手机号asyncgetAnonymousPhone(){//匿名手机号letanonymousPhone:string// 创建授权请求并设置参数constauthRequestnewauthentication.HuaweiIDProvider().createAuthorizationWithHuaweiIDRequest();// 获取匿名手机号需传quickLoginAnonymousPhone这个scope传参之前需要先申请“华为账号一键登录”权限authRequest.scopes[quickLoginAnonymousPhone];// 用于防跨站点请求伪造authRequest.stateutil.generateRandomUUID();// 一键登录场景该参数必须设置为falseauthRequest.forceAuthorizationfalse;constcontrollernewauthentication.AuthenticationController();try{letresponse:authentication.AuthorizationWithHuaweiIDResponseawaitcontroller.executeRequest(authRequest)anonymousPhoneresponse.data?.extraInfo?.quickLoginAnonymousPhoneasstring;}catch(error){}returnanonymousPhone}//初始化asyncaboutToAppear(){//获取匿名手机号this.phoneawaitthis.getAnonymousPhone()}build(){Navigation(){Column(){// logoImage($r(app.media.logo)).width(100).height(100).borderRadius(20).margin({top:80})// 匿名手机号Text(this.phone).fontSize(40).margin({top:60})Text(华为账号绑定号码).fontSize(13).fontColor(#999).margin({top:10})Column(){//一键登录按钮LoginWithHuaweiIDButton({params:{// LoginWithHuaweiIDButton支持的样式style:loginComponentManager.Style.BUTTON_RED,// 账号登录按钮在登录过程中展示加载态extraStyle:{buttonStyle:newloginComponentManager.ButtonStyle().loadingStyle({show:true})},// LoginWithHuaweiIDButton的边框圆角半径borderRadius:24,// LoginWithHuaweiIDButton支持的登录类型loginType:loginComponentManager.LoginType.QUICK_LOGIN,customButtonParams:{backgroundColor:rgba(255,255,255,0.6)},// LoginWithHuaweiIDButton支持按钮的样式跟随系统深浅色模式切换supportDarkMode:true,// verifyPhoneNumber如果华为账号用户在过去90天内未进行短信验证是否拉起Account Kit提供的短信验证码页面verifyPhoneNumber:true},controller:this.controller}).width(100%).height(48)//其他登录按钮Button(其他方式登录).margin({top:16}).height(48).width(100%).backgroundColor(#F2F2F2).fontColor(#000)}.margin({top:50})Blank()//隐私协议Row(){//勾选框Column(){if(this.isAgree){Image($r(app.media.checked)).width(18)}else{Circle({width:18,height:18}).stroke(#999).fill(rgba(0,0,0,0))}}.onClick((){this.isAgree!this.isAgree//设置协议状态this.controller.setAgreementStatus(this.isAgree?loginComponentManager.AgreementStatus.ACCEPTED:loginComponentManager.AgreementStatus.NOT_ACCEPTED);})//协议文字Flex({direction:FlexDirection.Row,alignItems:ItemAlign.Start,wrap:FlexWrap.Wrap}){Text(已阅读并同意).custText(#999)Text(《xxxx用户协议》).custText(#000)Text(《xxxx用户协议》).custText(#000)Text(和).custText(#999)Text(《华为账号用户认证协议》).custText(#000).onClick((){router.pushUrl({url:pages/agreement})})}.margin({left:8})}.width(100%).padding({left:10})}.padding(20).height(100%)}.hideTitleBar(true).hideToolBar(true).height(100%).width(100%)}}Extend(Text)functioncustText(fontColor:ResourceColor){.fontSize(12).fontColor(fontColor).lineHeight(18)}enumErrorCode{// 账号未登录ERROR_CODE_LOGIN_OUT1001502001,// 该账号不支持一键登录如儿童账号、海外账号ERROR_CODE_NOT_SUPPORTED1001500003,// 网络错误ERROR_CODE_NETWORK_ERROR1001502005,// 用户未同意用户协议ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED1005300001,// 参数错误ERROR_CODE_PARAMETER_ERROR401}Agreement.ets华为账号用户认证协议页/** * 华为账号用户认证协议页 */import{webview}fromkit.ArkWeb;Entry Component struct Agreement{State webUrl:stringhttps://privacy.consumer.huawei.com/legal/id/authentication-terms.htm?codeCNlanguagezh-CNprivatecontroller:webview.WebviewControllernewwebview.WebviewController()build(){Navigation(){Web({src:this.webUrl,controller:this.controller}).zoomAccess(false).height(100%).width(100%)}.title(华为账号用户认证协议).titleMode(NavigationTitleMode.Mini)}}