【接入指南】華為帳號服務Authorization Code模式介紹與接入步驟詳解


華為帳號服務提供兩種登錄授權模式,第一種是Authorization Code模式,第二種是ID-Token模式,這兩種模式在使用場景上存在差異。本文將詳細介紹Authorization Code模式及其接入方法,下一篇文章將給大家詳解ID-Token模式。

Authorization Code模式介紹

使用場景:僅適用於開發者有自己的應用服務器場景。

優勢:首次登錄時,要求用戶同意授權,當身份驗證信息到期時,只需要從服務器端通過Refresh Token刷新Access Token令牌,不需要重復請求用戶授權,體驗更優。

業務流程:

Authorization Code模式接入步驟詳解

1、 環境配置

推薦使用HMS Toolkit插件進行環境配置,更加方便、快捷。

2、 客戶端開發:

(1)       展示華為帳號登錄圖標

華為帳號提供了一個按鈕控件HuaweiIdAuthButton,此控件展示華為風格的登錄按鈕,可以讓您方便快速地實現符合華為圖標使用規范的登錄按鈕。

使用方法:在xml布局文件中添加如下聲明,並通過不同可選參數調整風格。

<com.huawei.hms.support.hwid.ui.HuaweiIdAuthButton
    android:id="@+id/HuaweiIdAuthButton"//自定義
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

 

(2)       編寫帳號登錄功能代碼:

private void signInCode() {
    mAuthParam = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
            .setAuthorizationCode()
            .createParams();
    mAuthService = AccountAuthManager.getService(AuthWithAuthCodeActivity.this, mAuthParam);
    startActivityForResult(mAuthService.getSignInIntent(), REQUEST_SIGN_IN_LOGIN_CODE);
}

在需要的Activity(如AuthWithAuthCodeActivity)中編寫如上signInCode()方法代碼。代碼中.setAuthorizatonCode()表示選擇Authorization Code模式請求獲取code。

之后在華為帳號登錄按鈕中綁定點擊事件,觸發按鈕點擊事件后執行signInCode()方法即可拉起基於Authorization Code模式的帳號登錄授權頁面。

 

(3)       登錄授權后處理登錄結果

 
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Process the sign-in authorization result and obtain an ID token from AuthHuaweiId.
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_SIGN_IN_LOGIN_CODE) {
        Task<AuthAccount> authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
        if (authAccountTask.isSuccessful()) {
            // The sign-in is successful, and the user's HUAWEI ID information and Code are obtained.
            AuthAccount authAccount = authAccountTask.getResult();
            Log.i("AuthWithAuthCodeActivity", "Authorization code:" + authAccount.getAuthorizationCode());
        } else {
            // The sign-in failed.
            Log.e("AuthWithAuthCodeActivity", "sign in failed : " +((ApiException)authAccountTask.getException()).getStatusCode());
 
        }
    }
}

當登錄授權成功后,通過authAccount.getAuthorizationCode()即可獲取到code。

 

(4)       獲取到code后,開發者需將code發送給應用服務器,該部分代碼由開發者根據自身設計自行開發。

至此,登錄授權功能的客戶端代碼開發完成。

 

3、 服務器側開發:

(1)       接收來自客戶端發送的code

該部分代碼由開發者根據自身設計自行開發。

(2)       用code換Access Token

應用服務器調用華為帳號服務器對應接口將code換成Access Token、Refresh Token。同時將Access Token、Refresh Token保存在應用服務器。

注:code有效期只有5分鍾,且用一次就會失效,失效后需要通知客戶端重新獲取用戶授權。

請求參數:

參數名

描述

grant_type

OAuth 2.0規范定義的字段,該值固定填“authorization_code”。

code

客戶端發送的授權碼

client_id

App ID,在創建應用后由華為開發者聯盟為應用分配的唯一標識。查詢方法請參見查看應用

client_secret

App SECRET,在創建應用后由華為開發者聯盟為應用分配公鑰。查詢方法請參見查看應用

redirect_uri

AppGallery Connect中設置應用服務器的回調地址,用於應用服務器在獲取用戶授權后獲取憑證Access Token。

請求示例:

POST /oauth2/v3/token HTTP/1.1
Host: oauth-login.cloud.huawei.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=CF3L7XyCVZi52XMdsUzD7Z6ap0/N2qExcNe0AMqTselTtNd1B4DUwTsQ/23FPZasC8yI29v+N2s2jMT/T2MXiuc+178I/sYuWVoTyqwBaDqVW82KCMqaxbeWBguH4hEENxmDSUIE61Qg5R1F074PiS+qJYnbLI2IBqatS37px8pn5qnuq5oX+UX8XN3/w8HLt4GpakW5Dk1v7hGs&
client_id={app_id}&
client_secret={app_secret}&
redirect_uri=https://www.example.com/redirect_uri

響應參數:

參數名

描述

access_token

用戶的Access Token。

refresh_token

如果應用申請帳號服務時,入參中包含access_type=offline,則會返回此參數,該參數用於刷新Access Token。

expires_in

Access Token的過期時間,以秒為單位。默認60分鍾過期。

id_token

如果應用申請帳號服務時,入參scope中包含openid,則會返回此參數(JWT格式數據),包含用戶基本帳號、用戶郵箱等信息。ID Token的描述信息請參見ID Token驗證接口中ID Token描述。

scope

生成的憑證Access Token中包含的scope。

token_type

固定返回Bearer,標識返回Access 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.eyJhdF9oYXNoIjoiM0hPdFZYOEdMcG1GSDBWRVlSc1BjdyIsImF1ZCI6IjEwMDczNTE2NyIsInN1YiI6Ik1ERTlYaWFoc3MwaWFFNXU2c09PaEY5Mlhvell0Rkt4bUdtbWlhNGtTaEJ3dklLR2ciLCJhenAiOiIxMDA3MzUxNjciLCJpc3MiOiJodHRwczovL2FjY291bnRzLmh1YXdlaS5jb20",
"scope": "openid profile email",
"token_type": "Bearer"
}

 

(3)       解析Access Token

獲取到Access Token,要對其進行解析鑒權,獲取Access Token中包含的union_id、open_id、expire_in、scope等信息。

請求示例:

POST /rest.php?nsp_fmt=JSON&nsp_svc=huawei.oauth2.user.getTokenInfo HTTP/1.1
Host: oauth-api.cloud.huawei.com
Content-Type: application/x-www-form-urlencoded
open_id=OPENID&
access_token=CFwaKaGpgXEj9LlsDKVARTUL7DFkvbAE2a22HYpRx%2F520JO5UvfWqSc6X7XUwf4Pzo5%2FxC8mByagdMPG%2FHeHDBldhW3tYizcw3xXSVwJPWK82C8zPM%3D

其中open_id為固定值“OPENID”。

響應示例:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"union_id": "MDHSI1UnQ9wzGzibtoqicNNnUmJbwhicPzHxxiaVHvMtmNd3xw",
"scope": "https://www.huawei.com/auth/account",
"open_id": "MDFAMzAwMDE3NTAxQGI4ODgzNWRmYjE4ZTI2NGFiaZDE2YjI5ODMwMDM3MDA0QDIxYWY3NzVkZmM1ODk1MWY4NzI4YzFiaNGJkMjE2Y2QyZTUxNzg3NzUzMDcyZTM4ZjkyZTQxYw",
"expire_in": 1123,
"client_id": "300017501"
}

響應參數說明:

參數

是否必選

參數類型

描述

client_id

Long

應用App ID。

expire_in

int

Access Token的過期時間,單位為秒。默認為60分鍾。

union_id

string

用戶的union_id,由用戶帳號和應用開發者帳號簽名而成,需要應用ID包含com.huawei.android.hms.account.getUnionId權限時才會返回。對於同一個用戶,同一個開發者帳號下管理的不同應用,UnionId值相同,它是開發者帳號的唯一標識

open_id

string

用戶的union_id,由用戶帳號和應用ID加密生成的,當Access Token為用戶級,且入參open_id為OPENID時才返回。同一個用戶,不同應用,OpenId值不同,它是用戶的唯一標識

scope

string

用戶授權scope列表,當Access Token為用戶級時才返回。

 

(4)       判斷Access Token、Refresh Token是否過期

A、 解析AT后,可獲取該AT的有效期時間(默認60分鍾),開發者可以根據這個時間進行倒計時判斷當前AT是否即將過期,做好提前保活;

B、  另一種方式是看用AT去獲取用戶信息的時候是否返回AT過期錯誤碼來判斷;

C、  RT是否過期(默認有效期180天)可以通過用RT換取AT時是否返回RT過期錯誤碼來判斷。

(5)       Access Token即將過期或已過期,可用Refresh Token去華為帳號服務器刷新Access Token

當Access Token未過期,用Refresh Token去刷新不會改變Access Token,但超時時間會刷新。

當Access Token已過期,用Refresh Token去刷新,會獲得一個新的Access Token。

RT刷新AT的接口與用Code換取AT的接口類似,只需要將grant_type 換成”refresh_token” 、code換成Refresh Token,同時去掉redirect_uri參數即可。

請求示例:

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.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI3ODI0NTY2Njc4OTgtc2M0MzE3Y2l0NGEwMjB0NzdrbGdsbWo1ZjA4YWtnMWIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI3ODI0NTY2Njc4OTgtN2NkNGJpYWRkaGVwNGc4cnZic2VlOGtwcDA5Zm1hNzIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDE3MTIxMzkwMzgwNDE2MDc0MTQiLCJlbWFpbCI6Inh1ZXpoZW5odWF0anVAc2l",
"expires_in": 3600,
"scope": "openid profile email",
"token_type": "Bearer"
}

 

(6)       Refresh Token過期后,應用服務器需通知客戶端重新申請用戶授權,重新獲取code,刷新AT和RT

該部分代碼由開發者根據自身設計自行開發。

(7)       使用Access Token去華為帳號服務器獲取用戶信息

應用已經獲取到Access Token並已申請帳號開放信息對應權限后,應用需要獲取帳號用戶名稱、頭像、手機號碼、年齡等信息。

請求示例:

POST /rest.php?nsp_svc=GOpen.User.getInfo HTTP/1.1
Host: account.cloud.huawei.com
Content-Type: application/x-www-form-urlencoded
access_token=CV46i%2BFdM3LEja3z7%2BjOGu27mNBsKwBznSoe4MMfKmNw4aGNLisoCKYgbSOJIVhWLOIIVr0nMwVXFu9AvFGKoJmGk%2FUZdMDytv2bsamauePs3FG6ZkU%3D&
getNickName=0

響應示例:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"displayName":"182******74",
"openID":"MDFAMTAxMDA1MTg1QGFlMzM0OWIyOGY0MzNiaNjI1MDRiaNTI5ODAxYTA3MDhkQDU1MDA4ZTZmNTA2ZTE4ZTg0Yzc2YTlmNGVmN2E1ZjY1OTg4NWRiaN2QxMzQyMDUzNGMzNTU0YWQ3",
"headPictureURL":"https://upfile-drcn.platform.hicloud.com/FileServer/image/b.0150086000130905592.20180407082531.08157939582468778294625163020035.1000.9C3EE92B95EFEF4CAC263604A15953F32C7BC9E8A47D52B774511F75EF34C0D4.jpg"
}

響應參數說明:

參數

是否必選

參數類型

描述

openID

string

用戶openID。

displayName

string

getNickName為0或不傳時,按照匿名化帳號、昵稱的先后順序返回。

getNickName為1時,按照昵稱、匿名化帳號的先后順序返回。

headPictureURL

string

用戶頭像。

mobileNumber

string

用戶手機號。

srvNationalCode

string

用戶服務地國家。

nationalCode

string

用戶注冊地。

birthDate

string

生日。

ageGroupFlag

Int

年齡段。

-1:年齡未知(沒輸入生日) 。

0:成人。

1:未成人,介於兒童和成人之間。

2:兒童。

email

string

用戶郵箱。

注:當應用有獲取頭像、手機號、服務地國家、注冊地、生日、年齡段、郵箱權限后才返回對應信息,獲取權限請參見帳號開放信息獲取流程

 

至此,基於code模式的應用服務端關鍵開發步驟完成。

服務端相關示例代碼可參考https://github.com/HMS-Core/huawei-account-demo/tree/master/Account-Server-Java-Demo

 

往期指南:

>>【接入指南】一文帶你了解華為帳號服務

>>【接入指南】一個Demo帶你玩轉華為帳號服務

華為帳號服務相關鏈接:

>>華為帳號服務詳細指導

>>codelab接入指導

>>視頻講解(請參考HMS 4.0視頻講解)

>>使用Toolkit快速集成華為帳號服務使用指導

 

原文鏈接:https://developer.huawei.com/...
原作者:胡椒


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM