1. 介绍
简介
HMS Core华为帐号注册用户量已达到10亿+,通过华为帐号可以一键登录应用,通过与华为帐号绑定,可以为应用快速引入新用户和登录。华为帐号开放遵循OAuth2.0以及OpenID Connect标准规范。
您将建立什么
在这个codelab中,您将创建Demo Project实现对华为帐号开放服务的API调用,通过Demo Project您可以体验到:
- 使用华为帐号授权登录的流程
- 获取华为帐号开放的用户基本信息(用户标识、头像、昵称等)
- 通过取消授权API接口取消应用的授权
您将会学到什么
- 如何在AppGallery Connect上创建应用
- 如何开通华为帐号服务
- 如何集成华为帐号服务的SDK
- 如何调用华为帐号服务的API接口
2. 您需要什么
硬件要求
- 开发计算机(台式机或笔记本电脑)。
- 预装了HMS Core(APK)5.0.0.300及以上版本的HarmonyOS系统的HUAWEI手机一部,用于真机调试运行Demo。
软件要求
- JDK 1.8及以上
- 安装HUAWEI DevEco Studio 2.1及以上
- HarmonyOS SDK API Version 5-Version 7
- 安装Node.js LTS
需要的知识点
4. 能力接入准备
集成HUAWEI HMS Core能力,需要完成以下准备工作:
- 在AppGallery Connect创建HarmonyOS应用
- 下载并安装Node.js
- 创建HUAWEI DevEco Studio的JavaScript工程
- 申请应用调试证书
- 注册调试设备
- 申请调试Profile
- 配置签名信息
- 生成签名证书指纹
- 配置签名证书指纹
5. 开通帐号服务
- 在华为开发者联盟AppGallery Connect中选择"我的项目",在项目列表中选择创建的应用,在"项目设置"页面中选择"API管理"。
- 打开"华为帐号"服务开关。
至此,已经为创建的应用开通了"华为帐号"服务。
6. 集成HMS Core SDK
添加agcconnect服务依赖
- 在HarmonyOS应用根目录下的"build.gradle"文件中添加如下的agcconnect服务依赖。
buildscript { dependencies { classpath 'com.huawei.ohos:hap:3.0.5.11' // 添加agconnect服务依赖 classpath 'com.huawei.agconnect:agcp-harmony:1.3.0.300' } }
- 在HarmonyOS应用"entry"目录下的"build.gradle"文件中添加如下的AGC插件配置。
在文件头部声明下一行添加如下配置。apply plugin: 'com.huawei.agconnect'
在"dependencies"中添加如下编译依赖。
dependencies { implementation 'com.huawei.hms:jsb-ohos-adapter:6.4.0.301' // agconnect依赖组件 implementation 'com.huawei.agconnect:agconnect-core-harmony:1.3.0.300' }
- 在entry/src/main目录下的config.json 文件添加如下配置。
"deviceConfig": { "default": { "allowComponentsProxy": true } }
配置JSB SDK
- 修改HarmonyOS应用"entry/src/main/java"目录下的"MyApplication"文件,重写onInitialize和onEnd方法,注册HMS Core服务。
import com.huawei.hms.jsb.adapter.har.bridge.HmsBridge; import ohos.aafwk.ability.AbilityPackage; public class MyApplication extends AbilityPackage { private HmsBridge mHmsBridge; @Override public void onInitialize() { // 注册HMS Core服务 mHmsBridge = HmsBridge.getInstance(); mHmsBridge.initBridge(this); super.onInitialize(); } @Override public void onEnd() { // 注销HMS Core服务 mHmsBridge.destoryBridge(); super.onEnd(); } }
- 在HarmonyOS应用"entry/src/main/js/default/app.js"文件中添加如下代码。
import {hmsjsb} from '@hw-hmscore/hms-js-base' export default { hmsData: { eventCallbackMap: {} }, onCreate() { console.info('AceApplication onCreate'); hmsjsb.init(this.hmsData.eventCallbackMap); }, onDestroy() { console.info('AceApplication onDestroy'); } }
下载HMS Core SDK
- 执行CMD命令打开命令行工具,执行cd命令进入HarmonyOS应用的"entry"目录。
- 执行NPM命令下载Base SDK。
npm install @hw-hmscore/hms-js-base
出现如下提示,说明下载成功:
npm WARN testtest@1.0.0 No description npm WARN testtest@1.0.0 No repository field. + @hw-hmscore/hms-js-base@6.4.0-301 added 1 package from 1 contributor in 1.192s
- 执行NPM命令下载Account SDK。
npm install @hmscore/hms-jsb-account@6.5.300
- 在HarmonyOS应用"entry/src/main/config.json"的module节点增加如下属性配置,其中"value"的值为开发者的OAuth 2.0客户端ID(在AppGallery Connect网站点击"我的项目",在项目列表中找到您的项目,在"项目设置 > 常规"页面的"应用"区域获取"OAuth 2.0客户端ID(凭据):Client ID"的值)。
"metaData": { "customizeData": [ { "name": "com.huawei.hms.client.appid", // 这里需要把"OAuth Client ID"替换为OAuth 2.0客户端ID "value": "OAuth Client ID" } ] }
同步工程
点击右上角"Sync Now",完成"build.gradle"文件的同步,将相关依赖下载到本地。
7. 界面设计
帐号的交互接口主要涉及登录、静默登录、退出帐号、取消授权。本次codelab中您可以在HUAWEI DevEco Studio工程中创建一个布局页面,参照下图进行UI设计。
8. 开发帐号授权功能
ID Token登录
整体流程
- 用户选择华为帐号登录方式登录应用。
- 应用向华为帐号SDK发起登录请求。
- 华为帐号SDK根据登录请求中携带的授权域(scopes)信息, 显式告知用户需要授权的内容。
- 华为帐号SDK拉起用户登录授权界面。
- 用户确认允许授权。
- 华为帐号SDK返回ID Token信息。
- 应用客户端获取到ID Token后,去华为帐号服务器验证ID Token有效性。
代码示例
- 展示华为登录方式图标。
应用在登录页面展示帐号登录方式的图标,华为登录方式图标规范请参见华为帐号登录图标使用规范。 - 调用HuaweiIdAuthParamsHelper的setIdToken方法请求授权。
import {HuaweiIdAuthParamsHelper, HuaweiIdAuthManager} from '@hmscore/hms-jsb-account'; // 构造参数 var signInOption = new HuaweiIdAuthParamsHelper().setIdToken().setProfile().build();
- 调用HuaweiIdAuthManager.getAuthApi().getSignInIntent方法拉起华为帐号登录授权页面,处理登录结果。
// HuaweiIdAuthManager.getAuthApi方法返回huaweiIdAuth对象,调用huaweiIdAuth.getSignInIntent方法 HuaweiIdAuthManager.getAuthApi().getSignInIntent(signInOption).then((result)=>{ // 登录成功,获取用户的华为帐号信息 console.info("signIn success"); console.info(JSON.stringify(result)); console.info("ID Token:" + result.getIdToken()); this.signInResult = "signIn success: " + JSON.stringify(result); }).catch((error)=>{ //登录失败 console.error("signIn fail"); console.error(JSON.stringify(error)); this.signInResult = "signIn fail: " + JSON.stringify(error); });
Authorization Code登录
帐号还支持使用Authorization Code授权登录。适用于拥有Server端的应用授权。
整体流程
- 用户选择华为帐号登录方式登录应用客户端。
- 应用客户端向华为帐号SDK发送请求,获取Authorization Code。
- 华为帐号SDK向华为帐号服务器发送请求,获取Authorization Code。
- 华为帐号SDK展示华为帐号服务器的用户登录授权界面,界面上会根据登录请求中携带的授权域(scopes)信息,显式告知用户需要授权的内容。
- 用户允许授权。
- 华为帐号客户端返回Authorization Code信息给华为帐号SDK。
- 华为帐号SDK返回Authorization Code信息给应用客户端。
- 应用客户端将获取到的Authorization Code信息发给应用服务器。
- 应用服务器向华为帐号服务器发送请求,获取Access Token、Refresh Token、ID Token信息。
- 华为帐号服务器返回Access Token、Refresh Token、ID Token信息。
代码示例
- 展示华为登录方式图标。
应用在登录页面展示华为帐号登录方式的图标,华为登录方式图标规范请参见华为帐号登录图标使用规范。 - 调用HuaweiIdAuthParamsHelper.setAuthorizationCode方法请求授权。
import {HuaweiIdAuthParamsHelper, HuaweiIdAuthManager} from '@hmscore/hms-jsb-account'; // 构造参数 var signInOption = new HuaweiIdAuthParamsHelper().setAuthorizationCode().setProfile().build();
- 调用HuaweiIdAuthManager.getAuthApi().getSignInIntent方法并拉起华为帐号登录授权页面,处理登录结果。
// HuaweiIdAuthManager.getAuthApi方法返回huaweiIdAuth对象,调用huaweiIdAuth.getSignInIntent方法 HuaweiIdAuthManager.getAuthApi().getSignInIntent(signInOption).then((result)=>{ // 登录成功,获取用户的华为帐号信息 console.info("signIn success"); console.info(JSON.stringify(result)); console.info("昵称:" + result.getDisplayName()); console.info("头像url:" + result.getAvatarUri()); this.signInResult = "signIn success: " + JSON.stringify(result); }).catch((error)=>{ //登录失败 console.error("signIn fail"); console.error(JSON.stringify(error)); this.signInResult = "signIn fail: " + JSON.stringify(error); });
- 登录成功后应用服务器调用"获取凭证Access Token的接口"向华为帐号服务器请求获取ID Token、Access Token、Refresh Token。
返回样例
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token": "CFyJ21sNODl16eV9y2vu3CwQk9DBr32BkOcxxgAd7MZUR5th1giyTk5\/kA+QDAyxou+\/5U2zzBRcf3qgLkkFdtbbC+mM3zFV7xj7CCEMHc5Tw92al0Y=", "refresh_token": "CF13G0sRaGybtYt7SIyeUILNORtTFwMgz4ao5C7j7vtgLPt6ogmXKjdI8RS\/YlyS71z4DyP6kEMnOrRlmNK0KhdOUNWd+qVLLRsEEHkqRIKpuAkPvL8=", "expires_in": 3600, "id_token": "eyJraWQiOiI3YTNlYjRkNTJmMDdhODM0NDU4MmRhOGQ3MWE1MGQ5MDlmNWM0YmRiZTFkNDQ3MjQ2MDNhZTA2NGM0ZTlkZGYyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJhdF9oYXNoIjoiM0hPdFZYOEdMcG1GSDBWRVlSc1BjdyIsImF1ZCI6IjEwMDczNTE2NyIsInN1YiI6Ik1ERTlYaWFoc3MwaWFFNXU2c09PaEY5Mlhvell0Rkt4bUdtbWlhNGtTaEJ3dklLR2ciLCJhenAiOiIxMDA3MzUxNjciLCJpc3MiOiJodHRwczovL2FjY291bnRzLmh1YXdlaS5jb20iLCJuYW1lIjoi6Jab5oyv5Y2OIiwiZXhwIjoxNTczMDQ2NDI4LCJnaXZlbl9uYW1lIjoi6Jab5oyv5Y2OIiwiZGlzcGxheV9uYW1lIjoi5rKh5pyJ562U5qGIIiwiaWF0IjoxNTczMDQyODI4LCJwaWN0dXJlIjoiaHR0cHM6Ly91cGZpbGUtZHJjbi5wbGF0Zm9ybS5oaWNsb3VkLmNvbS9GaWxlU2VydmVyL2ltYWdlL2IuMDI2MDA4NjAwMDIzMjQ3MjUxMS4yMDE5MDgyMDExNTQ0Mi5tbmRjWTZyN2JUT0xNcVdiNVBhZDIzZExWNXh0b1Z2WC4xMDAwLkI0QkUyQTdEM0I3NkFGMzBCMkJDNjlBQ0JFNjg3NDIxMTQwMjhEQzYwREZFOTVCMjM5QkI0QzM2OUQwOUVEMkEuanBnIn0.mqy2C3ZNYEM8FKt8r1LX0VFosJjpqVl7E7mw2N-uEhnmAJq3blBco8fp2TCEyUzi1qFMN7-cjv87mQqCEpgfozyU7xV0VXMGdcd9ZhOxtabZtQGxUXRpIPiK5iysp68d95_QJAf2YZIdA4P_1zU8ZGxH57njIXRUVdQWDB8poeuB9gOc72bufe3DmSkqYD9aKvcibpA44Iln58aj-I9xs-FpcDwE6Y9hTfLGT5vk_5hXs32qwt54kEH1JjKbzZRW7B-OaELJIzzOM49oZKrdkViG6c2Tco1xX1WcKSz298Wckj4suLBAqkam4AprQgoSETC__ORTfy9OHIS1m4_8uQ", "scope": "openid profile email", "token_type": "Bearer" }
- 由于Access Token的有效期(目前是60分钟)较短,当Access Token失效或者即将失效时,可以使用Refresh Token(当前默认有效期180天)通过"获取凭证Access Token的接口"向华为帐号服务器请求获取新的Access Token。
请求样例POST /oauth2/v3/token HTTP/1.1 Host: oauth-login.cloud.huawei.com Content-Type: application/x-www-form-urlencoded grant_type=refresh_token& client_id=12345& client_secret=bKaZ0VE3EYrXaXCdCe3d2k9few& refresh_token=CF2Mm03n0aos9iZZ8nIhfyDtoXy74CXeBi50gVVhMpB0IUzlv9ZwizEvTBhVoF820ZPim0JwNR9j2p1qgEQWnIVYZRlp4T6ezMgekUnsHBkvNev5rd2MdfQMLP
返回样例
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token": "CFyJ4J\/l6wuwcFqYOJG4maq2ca8RAV+g0i+mel6qCV5lvqH0PYtW0+BNwfHWg0AqMnW6ZdBvUgs7ijkxMFh1xVP\/B+vQXz3PWsivkKCuL78XtbLt7vs=", "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjExOGRmMjU0YjgzNzE4OWQxYmMyYmU5NjUwYTgyMTEyYzAwZGY1YTQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI3ODI0NTY2Njc4OTgtc2M0MzE3Y2l0NGEwMjB0NzdrbGdsbWo1ZjA4YWtnMWIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI3ODI0NTY2Njc4OTgtN2NkNGJpYWRkaGVwNGc4cnZic2VlOGtwcDA5Zm1hNzIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDE3MTIxMzkwMzgwNDE2MDc0MTQiLCJlbWFpbCI6Inh1ZXpoZW5odWF0anVAc2luYS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwicGljdHVyZSI6Imh0dHBzOi8vbGg1Lmdvb2dsZXVzZXJjb250ZW50LmNvbS8tMm9lTTllT09zNTAvQUFBQUFBQUFBQUkvQUFBQUFBQUFBQkkvMVpOSC0xdmxxc3cvczk2LWMvcGhvdG8uanBnIiwiaWF0IjoxNTYxNDUxMTUyLCJleHAiOjE1NjE0NTQ3NTJ9.Eo9IHMkid596jvt1YYzNsRtDq9c9K9dbougkU41Noh7TXNiko86_RuWwHID6k1kDg398AwC3wwH-t2hLcUjgrXPNd9XYU96Jp4-UxdDszP6ywEJgvvBCyTHzsi2auvKt_MnfSrs3qOKfh7noJvXq8AY-Hi3vqSUks5kGqbZKVzCHhBDO3RD9Fs9YHsB6w0XVKZojPOBDaAT_TiijoChn-Q-e8NbSGUx52OgeH-Nw5lOj6JVb_7fb6ucWRzlhiQuzFjklevLVw2pjw1MxKbl1vfRp0X699uZBVjgl9hj1L7LSDObuPzLiXF7ojji5JKYC6zIwAtZQUZ_VUmSk01GDLQ", "expires_in": 3600, "scope": "openid profile email", "token_type": "Bearer" }
静默登录
整体流程
- 用户进行了触发静默登录的场景,根据应用实际场景由您自行设定。
- 应用调用HuaweiIdAuthParamsHelper的默认构造方法配置鉴权参数。
- 华为帐号SDK向应用返回包含授权参数的HuaweiIdAuthParams对象。
- 应用调用HuaweiIdAuthManager.getAuthApi().silentSignIn方法向华为帐号SDK发起静默登录请求。
- 华为帐号SDK检查用户是否符合静默登录的授权,并向应用返回授权结果。
- 应用根据授权结果自行确定后续处理。
代码示例
- 调用HuaweiIdAuthParamsHelper的默认构造方法配置鉴权参数,返回保护授权参数的HuaweiIdAuthParams对象。
import {HuaweiIdAuthParamsHelper, HuaweiIdAuthManager} from '@hmscore/hms-jsb-account'; // 构造参数 var signInOption = new HuaweiIdAuthParamsHelper().setAuthorizationCode().setAccessToken().setIdToken().setId().setProfile().build();
- 调用HuaweiIdAuthManager.getAuthApi().silentSignIn方法发起静默登录请求,异步处理登录结果。
// HuaweiIdAuthManager.getAuthApi方法返回huaweiIdAuth对象,调用huaweiIdAuth.silentSignIn方法 HuaweiIdAuthManager.getAuthApi().silentSignIn(signInOption).then((result)=>{ //登录成功,获取用户的华为帐号信息 console.info("signIn success"); console.info("昵称:" + result.getDisplayName()); console.info("头像url:" + result.getAvatarUri()); console.info(JSON.stringify(result)); }).catch((error)=>{ //登录失败 console.error("signIn fail"); console.error(JSON.stringify(error)); });
退出帐号
整体流程
- 用户已经登录应用,在应用中执行退出操作。
- 应用调用HuaweiIdAuthManager.getAuthApi().signOut方法向华为帐号SDK请求退出华为帐号。
- 华为帐号SDK清除华为帐号登录信息后向应用返回退出结果。
代码示例
调用HuaweiIdAuthManager.getAuthApi().signOut方法向华为帐号SDK请求退出华为帐号。
import {HuaweiIdAuthManager} from '@hmscore/hms-jsb-account';
// HuaweiIdAuthManager.getAuthApi方法返回huaweiIdAuth对象,调用huaweiIdAuth.signOut方法
HuaweiIdAuthManager.getAuthApi().signOut().then((result)=>{
//帐号退出成功
console.info("signOut success");
console.info(JSON.stringify(result));
this.signOutResult = "signOut success: " + JSON.stringify(result);
}).catch((error) => {
//帐号退出失败
console.error("signout fail");
console.error(JSON.stringify(error));
this.signOutResult = "signOut fail: " + JSON.stringify(error);
});
帐号取消授权
整体流程
- 用户已经登录应用并授权,在应用中执行取消授权。
- 应用调用HuaweiIdManager.getAuthApi().cancelAuthorization方法向华为帐号SDK请求取消授权。
- 华为帐号SDK调用HuaweiIdManager.getAuthApi().cancelAuthorization方法向华为帐号服务器请求取消授权。
- 华为帐号服务器清理华为帐号授权信息后向华为帐号SDK返回取消结果。
- 华为帐号SDK清理华为帐号授权信息后向应用返回取消结果。
代码示例
- 应用设置取消授权入口,此部分由应用自行开发。
- 应用调用HuaweiIdManager.getAuthApi().cancelAuthorization方法,并处理返回结果。
import {HuaweiIdAuthManager} from '@hmscore/hms-jsb-account'; // HuaweiIdAuthManager.getAuthApi方法返回huaweiIdAuth对象,调用huaweiIdAuth.cancelAuthorization方法 HuaweiIdAuthManager.getAuthApi().cancelAuthorization(signInOption).then((result)=>{ //帐号取消授权成功 console.info("cancelAuthorization success"); console.info(JSON.stringify(result)); this.signOutResult = "signOut success: " + JSON.stringify(result); }).catch((error) => { //帐号取消授权失败 console.error("cancelAuthorization fail"); console.error(JSON.stringify(error)); this.signOutResult = "signOut fail: " + JSON.stringify(error); });
9. 打包测试
开发完成后,点击图标,运行HUAWEI DevEco Studio工程打包生成HAP,并安装在测试手机上。运行界面如下图所示:
10. 恭喜您
干得好,您已经成功完成了codelab并学到了:
- 如何在AppGallery Connect上创建应用
- 如何开通华为帐号服务
- 如何集成华为帐号服务的SDK
- 如何调用华为帐号服务的API接口