使用“华为账号登录”按钮登录
场景介绍
应用可以使用Account Kit提供的华为账号登录按钮及服务端交互获取华为账号用户身份标识UnionID、OpenID,通过UnionID、OpenID完成用户登录;或者与应用账号完成绑定,绑定后用于登录或者验证。
华为账号登录按钮包含文本、标志和文本、标志三种样式,以满足应用对界面风格一致性和灵活性的要求。

约束与限制
华为账号按钮登录能力支持Phone、Tablet、PC/2in1设备。并且从5.1.1(19)版本开始,新增支持TV设备。
用户体验设计

账号登录按钮的用户体验和UX设计需符合【华为账号登录】按钮规范,不符合规范的UX设计可能会对应用上架和用户体验带来影响。
业务流程

流程说明:
-
调用登录按钮展示登录页阶段(序号1-3):
- 用户打开应用进行登录,应用设置LoginType类型为LoginType.ID后拉起应用自己的登录页并展示“华为账号登录”按钮,用户点击按钮,请求华为账号授权信息。
-
用户点击登录阶段(序号4-6):
- 如华为账号未登录,将拉起华为账号登录页,用户登录后,将返回Authorization Code等数据给应用。
- 如华为账号已登录,将直接返回Authorization Code等数据给应用。
-
用户关联应用账号阶段(序号7-16):
- 应用服务端通过Authorization Code获取到Access Token,再使用Access Token调用解析凭证接口获取用户相关信息。通过Authorization Code凭证获取用户信息可以有效避免黑客通过数据遍历、身份伪造、重放攻击等手段导致的安全风险。
- 应用服务端将业务登录凭证SessionId、UnionID/OpenID传给应用,应用获取到UnionID/OpenID可用于判断华为账号是否登录等功能。
- 应用对用户身份标识UnionID/OpenID、业务登录凭证SessionId信息进行认证后,通过UnionID/OpenID判断用户是否已关联应用系统数据库,如已关联,则完成用户登录;如未关联,则创建新用户,绑定UnionID/OpenID。
接口说明
华为账号登录按钮关键接口如下表所示:
| 接口名 | 描述 |
|---|---|
| LoginWithHuaweiIDButton | 华为账号Button登录组件。 当前该组件支持Icon类型按钮、纯文本按钮、Icon和文本混合按钮,如果仍然不能满足开发者的诉求,可以使用Style的BUTTON_CUSTOM值定义按钮的文字颜色和背景色。 |
| onClickLoginWithHuaweiIDButton(callback: AsyncCallback<HuaweiIDCredential>): LoginWithHuaweiIDButtonController | 注册华为账号登录按钮的登录事件结果回调。使用callback异步回调。 |
| setAgreementStatus(agreementStatus: AgreementStatus): LoginWithHuaweiIDButtonController | 设置协议状态方法。如果需要用户同意协议才能完成华为账号登录,请先设置协议状态为NOT_ACCEPTED,当用户同意协议后设置协议状态为ACCEPTED,才可以完成华为账号登录。 |
上述接口需在页面或自定义组件生命周期内调用。
开发前提
在进行代码开发前,请确保已按照“开发准备”章节中的指导完成配置签名和指纹、配置Client ID。此场景无需申请账号权限。
客户端开发
-
导入LoginWithHuaweiIDButton模块及相关公共模块。
import { LoginWithHuaweiIDButton, loginComponentManager } from '@kit.AccountKit';import { BusinessError } from '@kit.BasicServicesKit';import { hilog } from '@kit.PerformanceAnalysisKit'; -
调用LoginWithHuaweiIDButton组件,展示华为账号登录按钮,用户点击华为账号登录按钮后,应用获取到Authorization Code、ID Token,将数据传给应用服务端,可参考客户端与服务端交互开发的开发步骤a和b,完成服务端开发。通过Authorization Code凭证获取用户信息可以有效避免黑客通过数据遍历、身份伪造、重放攻击等手段导致的安全风险。应用可以通过公开的网址获取到华为账号服务器发布的公钥,对签名和ID Token中的必要信息进行验证,以证明其没有被篡改过。解析ID Token可参考ID Token解析与验证。
@Entry@Componentstruct PreviewLoginButtonPage {// 构造LoginWithHuaweiIDButton组件的控制器controller: loginComponentManager.LoginWithHuaweiIDButtonController =new loginComponentManager.LoginWithHuaweiIDButtonController().onClickLoginWithHuaweiIDButton((error: BusinessError, response: loginComponentManager.HuaweiIDCredential) => {if (error) {this.dealAllError(error);return;}if (response) {hilog.info(0x0000, 'testTag', 'Succeeded in getting response.');const authCode = response.authorizationCode;// 开发者处理authCode}});// 错误处理dealAllError(error: BusinessError): void {hilog.error(0x0000, 'testTag',`Failed to login, errorCode is ${error.code}, errorMessage is ${error.message}`);// 在应用登录涉及UI交互场景下,建议按照如下错误码指导提示用户if (error.code === ErrorCode.ERROR_CODE_LOGIN_OUT) {// 用户未登录华为账号,请登录华为账号并重试或者尝试使用其他方式登录} else if (error.code === ErrorCode.ERROR_CODE_NETWORK_ERROR) {// 网络异常,请检查当前网络状态并重试或者尝试使用其他方式登录} else if (error.code === ErrorCode.ERROR_CODE_INTERNAL_ERROR) {// 登录失败,请尝试使用其他方式登录} else if (error.code === ErrorCode.ERROR_CODE_USER_CANCEL) {// 用户取消授权} else if (error.code === ErrorCode.ERROR_CODE_SYSTEM_SERVICE) {// 系统服务异常,请稍后重试或者尝试使用其他方式登录} else if (error.code === ErrorCode.ERROR_CODE_REQUEST_REFUSE) {// 重复请求,应用无需处理} else if (error.code === ErrorCode.ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED) {// 用户未同意协议} else {// 应用登录失败,请尝试使用其他方式登录}}build() {Column() {Column() {Column() {LoginWithHuaweiIDButton({params: {// LoginWithHuaweiIDButton支持的样式style: loginComponentManager.Style.BUTTON_RED,// 账号登录按钮在登录过程中展示加载态extraStyle: {buttonStyle: new loginComponentManager.ButtonStyle().loadingStyle({show: true})},// LoginWithHuaweiIDButton的边框圆角半径borderRadius: 24,// LoginWithHuaweiIDButton支持的登录类型loginType: loginComponentManager.LoginType.ID,// LoginWithHuaweiIDButton支持按钮的样式跟随系统深浅色模式切换supportDarkMode: true},controller: this.controller})}.height(40)}.width('100%')}.justifyContent(FlexAlign.Center).constraintSize({ minHeight: '100%' }).margin({left: 16,right: 16})}}export enum ErrorCode {// 账号未登录ERROR_CODE_LOGIN_OUT = 1001502001,// 网络错误ERROR_CODE_NETWORK_ERROR = 1001502005,// 内部错误ERROR_CODE_INTERNAL_ERROR = 1001502009,// 用户取消授权ERROR_CODE_USER_CANCEL = 1001502012,// 系统服务异常ERROR_CODE_SYSTEM_SERVICE = 12300001,// 重复请求ERROR_CODE_REQUEST_REFUSE = 1001500002,// 用户未同意用户协议ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED = 1005300001}
服务端开发
-
应用服务端使用Client ID、Client Secret、Authorization Code调用获取用户级凭证接口向华为账号服务器请求获取Access Token、Refresh Token。
-
使用Access Token调用解析凭证接口获取用户的UnionID。
Access Token过期处理
由于Access Token的有效期仅为60分钟,当Access Token失效或者即将失效时(可通过REST API错误码判断),可以使用Refresh Token(有效期180天)通过刷新用户级凭证接口向华为账号服务器请求获取新的Access Token。
- 当Access Token失效时,若应用不使用Refresh Token向华为账号服务器请求获取新的Access Token,账号的授权信息将会失效,导致使用Access Token的功能都会失败。
- 当Access Token非正常失效(如修改密码、退出账号、删除设备)时,应用可重新登录授权获取Authorization Code,向华为账号服务器请求获取新的Access Token。
Refresh Token过期处理
由于Refresh Token的有效期为180天,当Refresh Token失效后(可通过REST API错误码判断),应用服务端需要通知客户端,重新调用授权接口,请求用户重新授权。
-
应用在自己的用户体系通过查询获取的UnionID判断该用户是否已关联。如已关联,则完成用户登录;如未关联,则创建新用户,绑定UnionID,完成用户登录。