公司动态
HarmonyOS掌上记账APP开发实践第46篇:Account Kit华为账号一键登录
046 — Account Kit 华为账号一键登录聚合登录组件的集成实践简介登录注册是用户使用应用的第一道门槛登录体验的好坏直接影响用户的转化率。MoneyTrack 采用聚合登录设计在一个页面中集中管理微信登录、手机号登录和华为账号一键登录三种方式。通过 Account Kit 集成华为账号登录能力用户无需输入手机号和验证码点击即可完成授权和登录大幅降低了登录门槛。LoginPage 中的 Channel 配置将三种登录方式统一抽象各渠道只需实现相同的接口即可无缝接入。huaweiAccount.getAuth() 完整参数说明调用huaweiAccount.getAuth()拉起华为账号授权页时支持以下完整参数配置参数类型必填说明scopesstring[]是请求的权限范围至少包含openidclientIdstring是AGC 控制台获取的 Client IDredirectUristring否OAuth 回调地址默认使用包名注册的回调statestring否防 CSRF 攻击的状态参数回调时会原样返回loginTypeLoginType否登录类型默认拉起授权页forceAuthorizationboolean否是否强制重新授权默认 falseimport{huaweiAccount}fromkit.AccountKit;interfaceAuthRequest{scopes:string[];clientId:string;redirectUri?:string;state?:string;forceAuthorization?:boolean;}// 实际调用constauthResultawaithuaweiAccount.getAuth({scopes:[openid,profile,phone],clientId:AppConfig.HUAWEI_CLIENT_ID,state:this.generateRandomState(),forceAuthorization:false});authResult返回对象包含以下字段字段类型说明accessTokenstring访问令牌用于获取用户信息openIdstring用户在应用内的唯一标识unionIdstring用户在开发者所有应用间的统一标识authorizationCodestring授权码可用于服务端换取 access_tokenstatestring请求时传入的 state 参数值OAuth 授权码模式的完整流程华为账号登录采用标准 OAuth 2.0 授权码模式Authorization Code Grant完整流程如下自有服务端AGC 授权服务器Account KitMoneyTrack用户自有服务端AGC 授权服务器Account KitMoneyTrack用户点击华为账号登录生成随机 state 参数getAuth({scopes, clientId, state})拉起系统授权页面确认授权返回 authorizationCode state校验 state 防止 CSRF发送 authorizationCode用 code 换取 access_token返回 access_token refresh_token用 access_token 获取用户信息返回用户信息昵称、头像等创建/更新用户账户返回登录态 token登录成功进入首页授权码模式的关键优势在于access_token 仅在服务端传输客户端只持有临时有效的 authorizationCode大大降低了 token 泄露的风险。聚合登录组件的完整架构聚合登录设计的核心是 Channel 抽象层通过统一的接口将所有登录渠道的管理集中化// 登录渠道抽象接口interfaceILoginChannel{type:string;icon:Resource;label:string;login():PromiseLoginResult;}// 各渠道实现classWeChatLoginimplementsILoginChannel{typeWeChat;icon$r(app.media.ic_wechat);label微信登录;asynclogin():PromiseLoginResult{// 微信 SDK 登录逻辑returnawaitwechatLogin();}}classHuaweiLoginimplementsILoginChannel{typeHW;icon$r(app.media.ic_huawei);label华为账号登录;asynclogin():PromiseLoginResult{constauthResultawaithuaweiAccount.getAuth({scopes:[openid,profile],clientId:AppConfig.HUAWEI_CLIENT_ID});// 获取用户信息constuserInfoawaithuaweiAccount.getUserInfo(authResult.accessToken);returnthis.handleAuthSuccess(authResult,userInfo);}privateasynchandleAuthSuccess(authResult:AuthResult,userInfo:UserInfo){// 将授权码发送到服务端完成登录returnawaitloginService.loginWithHuawei(authResult.authorizationCode);}}// 聚合登录组件Componentexportstruct AggregatedLogin{privatechannels:ILoginChannel[][newWeChatLogin(),newPhoneLogin(),newHuaweiLogin()];build(){Column(){Text(其他登录方式).fontSize(14).fontColor(#999);Row(){ForEach(this.channels,(channel:ILoginChannel){Button(){Image(channel.icon).width(48).height(48);Text(channel.label).fontSize(12);}.onClick(async(){try{constresultawaitchannel.login();if(result.success){this.onLoginSuccess(result);}}catch(error){this.onLoginError(channel.type,error);}})})}}}}权限和 scope 说明华为账号登录涉及以下 scope 权限Scope说明是否默认用途openid用户唯一标识是必须区分不同用户profile用户基本信息否获取昵称、头像phone手机号否获取用户手机号email邮箱地址否获取用户邮箱unionid统一标识否跨应用识别同一用户在module.json5中配置 metadata{module:{metadata:[{name:huawei_app_client_id,value:123456789}],requestPermissions:[{name:ohos.permission.GET_ACCOUNTS_OPENID,reason:用于华为账号一键登录}]}}登录失败处理完善的错误处理机制能提升用户体验。不同阶段的失败应有不同的处理策略exportclassLoginErrorHandler{statichandleLoginError(channelType:string,error:Error):UserMessage{consterrorCodethis.parseErrorCode(error);switch(errorCode){caseUSER_CANCEL:return{type:info,message:已取消登录};caseAUTH_DENIED:return{type:warning,message:请授权必要信息以完成登录,action:retry};caseNETWORK_ERROR:return{type:error,message:网络连接失败请检查网络后重试,action:retry};caseTOKEN_EXPIRED:return{type:error,message:登录已过期请重新授权,action:reauth};caseACCOUNT_DISABLED:return{type:error,message:该账号已被禁用请联系客服,action:contact};default:return{type:error,message:登录失败请稍后重试,action:retry};}}// 尝试静默重新授权staticasyncsilentReauth():PromiseAuthResult|null{try{returnawaithuaweiAccount.getAuth({scopes:[openid,profile],clientId:AppConfig.HUAWEI_CLIENT_ID,forceAuthorization:false});}catch{returnnull;}}}最佳实践优先使用授权码模式authorizationCode 是一次性且有时效的比直接将 access_token 暴露在客户端更安全。CSRF 防护不可省略每次请求生成随机 state 参数在回调中校验 state 一致性防止跨站请求伪造攻击。支持静默登录通过forceAuthorization: false尝试静默重新授权当 token 过期时无缝刷新不给用户中断感。scope 按需申请只申请当前需要的 scope 权限如仅登录就只申请 openidprofile避免过度索权引发用户警惕。优雅降级华为账号登录失败时应自动降级到其他可用的登录方式而非直接阻塞用户。聚合登录统一异常处理通过统一的 ErrorHandler 处理各渠道错误避免重复代码保持用户提示风格一致。项目代码案例文件路径feature_login/LoginPage.etsimport{huaweiAccount}fromkit.AccountKit;asyncfunctionloginWithHuawei(){try{constauthResultawaithuaweiAccount.getAuth({scopes:[openid,profile],clientId:AppConfig.HUAWEI_CLIENT_ID,state:generateRandomState()});// 将 authorizationCode 发送到服务端constserverResultawaitloginService.exchangeCodeForToken(authResult.authorizationCode,authResult.state);if(serverResult.success){awaithandleLoginSuccess(serverResult.userInfo);}}catch(error){constmessageLoginErrorHandler.handleLoginError(HW,error);showToast(message);}}文件路径feature_login/components/aggregated_login聚合登录组件constLOGIN_CHANNELS[{type:WeChat,icon:$r(app.media.ic_wechat),label:微信登录},{type:Phone,icon:$r(app.media.ic_phone),label:手机号登录},{type:HW,icon:$r(app.media.ic_huawei),label:华为账号登录}];聚合登录方案的核心优势是扩展性强——后续如需新增 Apple 登录或 QQ 登录只需添加新的 Channel 实现类和对应的 UI 配置即可无需修改现有登录页面逻辑。推荐参考文档Account Kit 华为账号登录指南OAuth 2.0 授权协议Account Kit API 参考