开天辟地 HarmonyOS(鸿蒙) - 华为账号: 华为账号的默认登录
开天辟地 HarmonyOS(鸿蒙) - 华为账号: 华为账号的默认登录
示例如下:
pages\account\HuaweiDefaultLoginDemo.ets
/*
* 华为账号的默认登录
*
* 关于示例代码,请参见 /HarmonyDemo/huaweilogindemo 目录中的 /huaweilogindemo/entry/src/main/ets/HuaweiDefaultLogin.ets
* 关于配置与证书之类的说明,请参见 /entry/src/main/ets/pages/account/readme.txt
*/
import { TitleBar } from '../TitleBar'
@Entry
@Component
struct HuaweiDefaultLoginDemo {
@State message: string = "请参见 /HarmonyDemo/huaweilogindemo 目录中的 /huaweilogindemo/entry/src/main/ets/HuaweiDefaultLogin.ets 中的示例"
build() {
Column({space:10}) {
TitleBar()
Text(this.message)
}
}
}
\huaweilogindemo\entry\src\main\ets\pages\HuaweiDefaultLogin.ets
/*
* 本例用于演示华为账号的默认的登录体验
* 登录后可以拿到 openID, unionID 等,以及华为账号头像和昵称等
*/
import { authentication } from '@kit.AccountKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct HuaweiDefaultLogin {
@State message: string = '';
/*
* LoginWithHuaweiIDRequest - 华为账号登录请求对象
* authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest() - 创建一个 LoginWithHuaweiIDRequest 对象
* forceLogin - 如果之前未在系统中登录华为账号,是否弹出默认登录页
* false - 如果之前未在系统中登录华为账号,则返回异常
* true - 如果之前未在系统中登录华为账号,则弹出默认登录页
* AuthenticationController - 用于控制华为账号登录
* authentication.AuthenticationController() - 创建一个 AuthenticationController 对象
* authentication.AuthenticationController(context) - 创建一个 AuthenticationController 对象(如果需要弹出默认登录页,则必须要传 context 参数)
* executeRequest() - 执行指定的 LoginWithHuaweiIDRequest 请求,返回一个 LoginWithHuaweiIDResponse 对象
* LoginWithHuaweiIDResponse - 华为账号登录的结果
* data - 一个 LoginWithHuaweiIDCredential 对象
* LoginWithHuaweiIDCredential - 当前登录的华为账号的相关信息
* authorizationCode - 临时凭据,用于获取 Access Token,有效时间 5 分钟
* idToken - JWT(JSON Web Token)格式的字符串,包含了一些用户信息
* openID - 华为账号用户在不同的应用中的身份ID,同一个用户,不同的应用,OpenID 值不同
* unionID - 华为账号用户在同一个开发者账号下的应用中的身份ID,同一个用户,同一个开发者账号下管理的不同应用,UnionID 值相同
*/
// 使用当前在系统中登录的华为账号做静默登录,如果之前未在系统中登录华为账号,则返回异常
private login1() {
this.message = "";
const loginRequest = new authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest();
loginRequest.forceLogin = false;
const controller = new authentication.AuthenticationController();
controller.executeRequest(loginRequest).then((data: authentication.LoginWithHuaweiIDResponse) => {
this.message += `登录成功\n`
const loginWithHuaweiIDCredential = data.data;
if (loginWithHuaweiIDCredential) {
this.message += `authorizationCode: ${loginWithHuaweiIDCredential.authorizationCode}\n`
this.message += `idToken: ${loginWithHuaweiIDCredential.idToken}\n`
this.message += `openID: ${loginWithHuaweiIDCredential.openID}\n`
this.message += `unionID: ${loginWithHuaweiIDCredential.unionID}\n`
}
}).catch((error: BusinessError) => {
this.message += `errCode:${error.code}, errMessage:${error.message}\n`
if (error.code === authentication.AuthenticationErrorCode.ACCOUNT_NOT_LOGGED_IN) {
this.message += `用户未登录华为账号\n`
}
});
}
// 使用当前在系统中登录的华为账号做静默登录,如果之前未在系统中登录华为账号,则弹出默认登录页
private login2() {
this.message = "";
const loginRequest = new authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest();
loginRequest.forceLogin = true;
const controller = new authentication.AuthenticationController(this.getUIContext().getHostContext());
controller.executeRequest(loginRequest).then((data: authentication.LoginWithHuaweiIDResponse) => {
this.message += `登录成功\n`
const loginWithHuaweiIDCredential = data.data;
if (loginWithHuaweiIDCredential) {
this.message += `authorizationCode: ${loginWithHuaweiIDCredential.authorizationCode}\n`
this.message += `idToken: ${loginWithHuaweiIDCredential.idToken}\n`
this.message += `openID: ${loginWithHuaweiIDCredential.openID}\n`
this.message += `unionID: ${loginWithHuaweiIDCredential.unionID}\n`
}
}).catch((error: BusinessError) => {
this.message += `errCode:${error.code}, errMessage:${error.message}\n`
if (error.code === authentication.AuthenticationErrorCode.ACCOUNT_NOT_LOGGED_IN) {
this.message += `用户未登录华为账号\n`
}
});
}
/*
* AuthorizationWithHuaweiIDRequest - 华为账号授权请求对象
* authentication.HuaweiIDProvider().createAuthorizationWithHuaweiIDRequest() - 创建一个 AuthorizationWithHuaweiIDRequest 对象
* forceLogin - 如果之前未在系统中登录华为账号,是否弹出默认登录页
* false - 如果之前未在系统中登录华为账号,则返回异常
* true - 如果之前未在系统中登录华为账号,则弹出默认登录页
* AuthenticationController - 用于控制华为账号授权
* authentication.AuthenticationController() - 创建一个 AuthenticationController 对象
* authentication.AuthenticationController(context) - 创建一个 AuthenticationController 对象(如果需要弹出默认登录页,则必须要传 context 参数)
* executeRequest() - 执行指定的 AuthorizationWithHuaweiIDRequest 请求,返回一个 AuthorizationWithHuaweiIDResponse 对象
* AuthorizationWithHuaweiIDResponse - 华为账号授权的结果
* data - 一个 AuthorizationWithHuaweiIDCredential 对象
* AuthorizationWithHuaweiIDCredential - 当前登录的华为账号的相关信息
* avatarUri - 头像地址
* nickName - 昵称
*/
// 使用当前在系统中登录的华为账号做静默登录,如果之前未在系统中登录华为账号,则弹出默认登录页
// 然后获取华为账号头像和昵称
private login3() {
this.message = "";
const authRequest = new authentication.HuaweiIDProvider().createAuthorizationWithHuaweiIDRequest();
authRequest.scopes = ['profile'];
authRequest.forceAuthorization = true;
const controller = new authentication.AuthenticationController(this.getUIContext().getHostContext());
controller.executeRequest(authRequest).then((data: authentication.AuthorizationWithHuaweiIDResponse) => {
this.message += `登录成功\n`
const authorizationWithHuaweiIDCredential = data.data;
if (authorizationWithHuaweiIDCredential) {
this.message += `avatarUri: ${authorizationWithHuaweiIDCredential.avatarUri}\n`
this.message += `nickName: ${authorizationWithHuaweiIDCredential.nickName}\n`
}
}).catch((error: BusinessError) => {
this.message += `errCode:${error.code}, errMessage:${error.message}\n`
if (error.code === authentication.AuthenticationErrorCode.ACCOUNT_NOT_LOGGED_IN) {
this.message += `用户未登录华为账号\n`
}
});
}
build() {
Column({space:10}) {
Button("静默登录,未登录则返回异常").onClick(() => {
this.login1();
})
Button("静默登录,未登录则弹出默认登录页").onClick(() => {
this.login2();
})
Button("静默登录,获取华为账号头像和昵称").onClick(() => {
this.login3();
})
Scroll() {
Text(this.message)
}.layoutWeight(1).align(Alignment.TopStart).backgroundColor(Color.Yellow).width('100%')
}
.width('100%')
.height('100%')
}
}
\entry\src\main\ets\pages\account\readme.txt
注:关于证书和华为账号登录的示例请参见 /huaweilogindemo 项目
几个概念:
AGC - AppGallery Connect
AGC 的地址 https://developer.huawei.com/consumer/cn/service/josp/agc/index.html
AGC 中的一个项目可以包含多个应用,这里所谓的项目比较类似分组的概念
.csr - 证书请求文件 Certificate Signing Request
.cer - AGC 上申请的证书文件的后缀名
.p7b - AGC 上申请的 profile 文件的后缀名
.p12 - 密钥库文件
证书相关:
1、生成证书请求文件
在 DevEco Studio 中选择 Build -> Generate Key and CSR
如果有密钥库文件(.p12)那么就选择它,如果没有则新建密钥库文件
选择好密钥库文件之后,设置一个秘钥别名(一个密钥库可以包含多个秘钥别名,一个秘钥别名对应一个 .csr 文件,后续在配置签名的时候会用到秘钥别名)
然后指定 .csr 文件的路径之后,就可以生成 .csr 文件了(建议 .csr 文件的文件名与秘钥别名一致)
注:选择保存路径的时候,最好都指向一个单独的文件夹,最终会生成一个 .p12 文件(密钥库文件),一个 .csr 文件(证书请求文件),一个名为 material 的文件夹(存放一些相关的资料)
2、在 AGC 的“证书、APP ID和Profile”中生成证书
证书类型分为“调试证书”和“发布证书”,为证书起名时,调试证书可以起名为:应用名称_debug,发布证书可以起名为:应用名称_release(注:证书的后缀名为 .cer)
选择 .csr 文件后就可以生成证书了
3、如果需要调试的话,则需要在 AGC 的“证书、APP ID和Profile”中注册调试设备,最多注册 100 个设备
获取设备的 UDID 的方法如下:
进入设备的“设置” -> “关于本机”,然后多次点击版本号,打开开发者模式
进入设备的“设置” -> “系统”,在最下方找到“开发人员选项”,然后打开“USB调试”开关
通过 hdc shell bm get --udid 获取设备的 UDID
hdc 的地址在 DevEco Studio 安装目录/sdk/default/openharmony/toolchains 中
4、在 AGC 的“证书、APP ID和Profile”中生成 profile
需要选择相关的证书
为 profile 起名时,调试 profile 可以起名为:应用名称_debug,发布 profile 可以起名为:应用名称_release(注:profile 的后缀名为 .p7b)
如果是调试 profile 还要选择已注册的设备
5、配置签名
在 DevEco Studio 中选择 File -> Project Structure -> Project -> Signing Configs 做配置(对应的配置文件为: 根目录/build-profile.json5)
调试场景时,可以使用自动签名也可以使用手动签名
发布场景时,只能使用手动签名
华为账号登录相关:
1、在 AGC 中创建相关的项目和相关的应用
2、在 AGC 中选择“我的项目”,然后点击相关的项目,然后点击相关的应用,然后在“常规”中找到指定应用的“OAuth 2.0客户端ID(凭据)”中的 Client ID
3、在本地开发项目中的 entry 模块的 module.json5 中做如下配置
"module": {
"type": "entry",
"metadata": [
{
"name": "client_id",
"value": "从 AGC 上拿到的指定应用的“OAuth 2.0客户端ID(凭据)”中的 Client ID"
}
]
}
4、配置证书指纹
在 DevEco Studio 中选择 File -> Project Structure -> Project -> Signing Configs
点击 Store file(*.p12): 最右侧的指纹按钮,然后复制证书指纹信息
在 AGC 中选择“我的项目”,然后点击相关的项目,然后点击相关的应用,然后在“常规”中找到指定应用的“SHA256证书/公钥指纹”,然后点击“添加证书指纹”,然后粘贴之前复制的证书指纹信息
5、配置公钥指纹
在 AGC 中选择“我的项目”,然后点击相关的项目,然后点击相关的应用,然后在“常规”中找到指定应用的“SHA256证书/公钥指纹”,然后点击“添加公钥指纹 (HarmonyOS API 9及以上)”,然后选择相关的公钥指纹信息即可
6、申请 scope 权限
进入 https://developer.huawei.com/consumer/cn/console/api/scopeManage
先在左上角选择好项目和凭证(凭证名称是由应用名称和应用的 APP ID 组成的),然后再查看或申请 scope 权限
默认有 openid, profile 权限,敏感权限需要单独申请