跳到主要内容

使用“华为账号登录”按钮登录

场景介绍

应用可以使用Account Kit提供的华为账号登录按钮及服务端交互获取华为账号用户身份标识UnionID、OpenID,通过UnionID、OpenID完成用户登录;或者与应用账号完成绑定,绑定后用于登录或者验证。

华为账号登录按钮包含文本、标志和文本、标志三种样式,以满足应用对界面风格一致性和灵活性的要求。

约束与限制

华为账号按钮登录能力支持Phone、Tablet、PC/2in1设备。并且从5.1.1(19)版本开始,新增支持TV设备。

用户体验设计

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

业务流程

流程说明:

  1. 调用登录按钮展示登录页阶段(序号1-3):

    1. 用户打开应用进行登录,应用设置LoginType类型为LoginType.ID后拉起应用自己的登录页并展示“华为账号登录”按钮,用户点击按钮,请求华为账号授权信息。
  2. 用户点击登录阶段(序号4-6):

    1. 如华为账号未登录,将拉起华为账号登录页,用户登录后,将返回Authorization Code等数据给应用。
    2. 如华为账号已登录,将直接返回Authorization Code等数据给应用。
  3. 用户关联应用账号阶段(序号7-16):

    1. 应用服务端通过Authorization Code获取到Access Token,再使用Access Token调用解析凭证接口获取用户相关信息。通过Authorization Code凭证获取用户信息可以有效避免黑客通过数据遍历、身份伪造、重放攻击等手段导致的安全风险。
    2. 应用服务端将业务登录凭证SessionId、UnionID/OpenID传给应用,应用获取到UnionID/OpenID可用于判断华为账号是否登录等功能。
    3. 应用对用户身份标识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。此场景无需申请账号权限。

客户端开发

  1. 导入LoginWithHuaweiIDButton模块及相关公共模块。

    import { LoginWithHuaweiIDButton, loginComponentManager } from '@kit.AccountKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { hilog } from '@kit.PerformanceAnalysisKit';
  2. 调用LoginWithHuaweiIDButton组件,展示华为账号登录按钮,用户点击华为账号登录按钮后,应用获取到Authorization Code、ID Token,将数据传给应用服务端,可参考客户端与服务端交互开发的开发步骤a和b,完成服务端开发。通过Authorization Code凭证获取用户信息可以有效避免黑客通过数据遍历、身份伪造、重放攻击等手段导致的安全风险。应用可以通过公开的网址获取到华为账号服务器发布的公钥,对签名和ID Token中的必要信息进行验证,以证明其没有被篡改过。解析ID Token可参考ID Token解析与验证

    @Entry
    @Component
    struct 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
    }

服务端开发

  1. 应用服务端使用Client ID、Client Secret、Authorization Code调用获取用户级凭证接口向华为账号服务器请求获取Access Token、Refresh Token。

  2. 使用Access Token调用解析凭证接口获取用户的UnionID。

    Access Token过期处理

    由于Access Token的有效期仅为60分钟,当Access Token失效或者即将失效时(可通过REST API错误码判断),可以使用Refresh Token(有效期180天)通过刷新用户级凭证接口向华为账号服务器请求获取新的Access Token。

    1. 当Access Token失效时,若应用不使用Refresh Token向华为账号服务器请求获取新的Access Token,账号的授权信息将会失效,导致使用Access Token的功能都会失败。
    2. 当Access Token非正常失效(如修改密码、退出账号、删除设备)时,应用可重新登录授权获取Authorization Code,向华为账号服务器请求获取新的Access Token。

    Refresh Token过期处理

    由于Refresh Token的有效期为180天,当Refresh Token失效后(可通过REST API错误码判断),应用服务端需要通知客户端,重新调用授权接口,请求用户重新授权。

  3. 应用在自己的用户体系通过查询获取的UnionID判断该用户是否已关联。如已关联,则完成用户登录;如未关联,则创建新用户,绑定UnionID,完成用户登录。