华为开发者论坛上有人发帖说,自己只有一个单机应用,没有服务器,该如何实现华为账号的登录功能呢?

我的App只有客户端,如何实现用户授权?-LMLPHP

首先我们要了解帐号登录是基于OAuth 2.0协议标准和OpenID Connect协议,它支持的授权登录方式有两种,Authorization Code和ID Token,也就是说应用可以通过获取帐号用户身份认证信息(ID Token)或用户的临时授权票据(Authorization Code),使用户安全登录。

什么是Authorization Code?

Authorization Code是一次性授权码,授权码和分配的AppSecret主要用来在OAuth服务器上进行身份验证。Authorization Code模式是一种临时性的授权票据模式,它仅适用于有自己服务器的应用。

什么是ID Token?

ID Token是已经登录用户的身份信息,其中包括用来验证身份信息的签名信息。ID Token模式就是用户身份认证信息的模式,这种模式同时适合单机应用和有自己服务器的应用。

接下来我们分别来看一下这两种登录模式:

Authorization Code登录

我的App只有客户端,如何实现用户授权?-LMLPHP

图中的Access Token,是用于访问用户资源的令牌,相当于钥匙;Refresh Token是旧访问令牌过期后获取新访问令牌的令牌。

按照上图流程,首先用户选择华为账号登录时,应用向HMS SDK发起登录请求。第2-5步,华为账号拉起用户登录授权界面,界面上会根据登录请求中携带的授权域即scope信息,显式告知用户需要授权的内容,用户点击确认授权。第7-9步,华为账号授权中心(HUAWEI ID OAuth server)返回Authorization Code信息。第10步,应用客户端把Authorization Code上传到应用服务器。第11-12步,应用服务器通过Authorization Code换取Access Token,Refresh Token,ID Token等信息。最后应用服务器使用Access Token从华为账号授权中心获取用户的openId等信息。如果Access Token或ID Token过期,应用服务器可以使用Refresh Token获取新的Access Token,ID Token的信息。

ID Token登录

我的App只有客户端,如何实现用户授权?-LMLPHP

ID Token的登录流程为,首先用户选择华为账号登录时,应用向HMS SDK发起登录请求。第2-14步,华为账号拉起用户登录授权界面,界面上会根据登录请求中携带的授权域即scope信息,显式告知用户需要授权的内容,用户点击确认授权。第15-17步,授权后HMS SDK直接返回ID Token等信息,应用获取到ID Token后,可以通过验证ID Token进行鉴权,关于ID Token的验证,请参考:本地验证或应用服务器验证

Authorization Code模式和ID Token模式是不同的,Authorization Code模式适用于有服务器的应用,通过AuthCode获取AccessToken,每次请求应用服务器时,应用服务器需要校验AccessToken的有效性来完成鉴权。ID Token模式是应用程序直接拿到用户的ID Token信息,使用应用时应用本地通过校验ID Token的有效性来完成鉴权。综上所述,当App只有客户端时,我们可以通过ID Token模式实现用户授权

ID Token模式开发步骤:

第一步,创建HuaweiIdAuthParams对象。

AccountAuthParams authParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setIdToken().createParams();

这是华为账号授权登陆参数的对象,包括了用户选择的登陆方式及授权域信息及Scope,就是用户给三方应用授予的权限范围,这个对象是通过HuaweiIdAuthParamsHelper对象来创建的,即我们要构建一个由默认参数构成的HuaweiIdAuthParams对象。接着调用的是setIdToken方法,即设置使用ID Token模式。

第二步,创建HuaweiIdAuthService对象。

AccountAuthService service = AccountAuthManager.getService(MainActivity.this, authParams);

HuaweiIdAuthService使用HuaweiIdAuthParams对象作为参数,它定义了静默授权、退出、取消授权等方法,其中getSignInIntent方法返回了一个intent对象。Intent对象是activity传递信息的媒介,它包含了启动授权activity的intent信息,客户端的后续操作都需要通过这个对象的API来完成,比如拉起授权页面、登出华为账号等功能。

我的App只有客户端,如何实现用户授权?-LMLPHP

第三步,调用startActivityForResult

startActivityForResult(service.getSignInIntent(), 8888);

我们使用HuaweiIdAuthService. getSignInIntent()方法中拿到的intent信息调用startActivityForResult方法拉起用户授权页面。

第四步,调用onActivityResult,从登录结果中获取帐号信息

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    //授权登录结果处理,从AuthAccount中获取ID Token
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 8888) {
        Task<AuthAccount> authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
        if (authAccountTask.isSuccessful()) {
            //登录成功,获取用户的帐号信息和ID Token
            AuthAccount authAccount = authAccountTask.getResult();
            Log.i(TAG, "idToken:" + authAccount.getIdToken());
            //获取帐号类型,0表示华为帐号、1表示AppTouch帐号
            Log.i(TAG, "accountFlag:" + authAccount.getAccountFlag());
        } else {
            //登录失败,不需要做处理,打点日志方便定位
            Log.e(TAG, "sign in failed : " +((ApiException) authAccountTask.getException()).getStatusCode());
        }
    }
}

用户授权成功后,我们可以在onActivityResult方法中获取到账号信息。其中通过AccountAuthManager.parseAuthResultFromIntent方法从intent数据中获取用户登陆信息,后续的步骤就是验证ID Token的有效性

我的App只有客户端,如何实现用户授权?-LMLPHP

>>访问华为开发者联盟官网,了解更多相关内容
>>获取开发指导文档
>>华为移动服务开源仓库地址:GitHubGitee

点击右上角头像右方的关注,第一时间了解华为移动服务最新技术

03-23 09:39