鑰匙環服務,打造無縫的跨設備登錄體驗

来源:https://www.cnblogs.com/hmscore/archive/2023/03/30/17272541.html
-Advertisement-
Play Games

近些年來,隨著手機技術迭代更新越來越快,用戶更換手機的周期也在縮短,在這樣的背景下,開發者不得不面臨以下問題: 同一開發者旗下常常有多個安卓應用和多形態應用(快應用和Web應用),用戶更換一個新的設備(手機或平板)後,在新設備上登錄各應用時每次都需要重覆輸入帳號和密碼,導致用戶在登錄階段流失率增加, ...


近些年來,隨著手機技術迭代更新越來越快,用戶更換手機的周期也在縮短,在這樣的背景下,開發者不得不面臨以下問題:

同一開發者旗下常常有多個安卓應用和多形態應用(快應用和Web應用),用戶更換一個新的設備(手機或平板)後,在新設備上登錄各應用時每次都需要重覆輸入帳號和密碼,導致用戶在登錄階段流失率增加,同時開發者還需要承擔額外的簡訊成本(如用戶使用簡訊登錄)。

華為HMS Core鑰匙環服務(Keyring)提供憑據管理介面(Credentials Management API),為Android手機、平板提供用戶登錄憑據存儲和跨應用、跨應用形態、跨設備共用的能力。

鑰匙環服務提供了Android APIWeb API快應用API,應用程式通過調用這些API來使用鑰匙環服務。無論調用哪種形式的介面,所有的用戶憑據最終都會存儲在HMS Core的鑰匙環服務中,以便實現統一的憑據管理能力和共用能力。

一、功能特點

鑰匙環服務提供登錄憑據本地儲存和跨形態、跨應用共用能力。鑰匙環服務將用戶登錄憑據加密儲存在本地設備,被保存的憑據通過鑰匙環服務共用至同一開發者旗下的其他快應用、Web應用和安卓應用;實現跨形態、跨應用無縫登錄體驗。

鑰匙環服務使用端到端加密同步技術實現登錄憑據跨設備同步能力。用戶在新老設備上打開“憑據多設備同步”功能,就可以在新設備上免密登錄同一開發者旗下的各形態應用,實現跨設備無縫登錄體驗。

例如,同一開發者將旗下的兩個安卓應用和兩個快應用接入鑰匙環服務後,用戶只需要在手機A和手機B上打開“憑據多設備同步”功能,手機A上登錄一個應用後,用手機B登錄時無需再輸入帳號和密碼,實現跨設備、跨應用、跨形態的無縫登錄體驗。

二、接入優勢

打造無縫登錄體驗

通過鑰匙環服務介面獲取本地存儲的用戶憑據,實現便捷登錄。

保障數據安全可靠

用戶登錄憑據在設備內加密存儲,在設備間通過端到端加密技術同步,雲端無法解密。

降低登錄流失率

簡化用戶登錄時操作流程,降低流失率

降低運營成本

減少使用簡訊登錄,降低運營成本

三、開發步驟

開發準備

詳細準備步驟可參考華為開發者聯盟官網

集成Keyring客戶端

用戶登錄場景

1、使用一個Activity實例初始化CredentialClient,可以寫在Activity的onCreate方法中。

CredentialClient credentialClient = CredentialManager.getCredentialClient(this);

2、查詢是否存在可用的憑據。

List<AppIdentity> trustedAppList = new ArrayList<>();
trustedAppList.add(new AndroidAppIdentity("yourAppName", "yourAppPackageName", "yourAppCodeSigningCertHash"));
trustedAppList.add(new WebAppIdentity("youWebSiteName", "www.yourdomain.com"));
trustedAppList.add(new WebAppIdentity("youWebSiteName", "login.yourdomain.com"));
SharedCredentialFilter sharedCredentialFilter = SharedCredentialFilter.acceptTrustedApps(trustedAppList);
credentialClient.findCredential(sharedCredentialFilter, new CredentialCallback<List<Credential>>() {
    @Override
    public void onSuccess(List<Credential> credentials) {
        if (credentials.isEmpty()) {
            Toast.makeText(MainActivity.this, R.string.no_available_credential, Toast.LENGTH_SHORT).show();
        } else {
            for (Credential credential : credentials) {
            }
        }
    }
    @Override
    public void onFailure(long errorCode, CharSequence description) {
        Toast.makeText(MainActivity.this, R.string.query_credential_failed, Toast.LENGTH_SHORT).show();
    }
});

3、調用Credential.getContent獲取憑據內容,在CredentialCallback獲取結果。

private Credential mCredential; 
//獲取的憑據
mCredential.getContent(new CredentialCallback<byte[]>() {
    @Override
    public void onSuccess(byte[] bytes) {
        String hint = String.format(getResources().getString(R.string.get_password_ok),
                new String(bytes));
        Toast.makeText(MainActivity.this, hint, Toast.LENGTH_SHORT).show();
        mResult.setText(new String(bytes));
    }
 
    @Override
    public void onFailure(long l, CharSequence charSequence) {
        Toast.makeText(MainActivity.this, R.string.get_password_failed,
                Toast.LENGTH_SHORT).show();
        mResult.setText(R.string.get_password_failed);
    }
});

4、用戶輸入了新憑據,調用憑據存儲介面。

AndroidAppIdentity app2 = new AndroidAppIdentity(sharedToAppName,
                sharedToAppPackage, sharedToAppCertHash);
List<AppIdentity> sharedAppList = new ArrayList<>();
sharedAppList.add(app2);

Credential credential = new Credential(username, CredentialType.PASSWORD, userAuth,
                password.getBytes());
credential.setDisplayName("user_niceday");
credential.setSharedWith(sharedAppList);
credential.setSyncable(true);

credentialClient.saveCredential(credential, new CredentialCallback<Void>() {
    @Override
    public void onSuccess(Void unused) {
        Toast.makeText(MainActivity.this,
                R.string.save_credential_ok,
                Toast.LENGTH_SHORT).show();
    }
 
    @Override
    public void onFailure(long errorCode, CharSequence description) {
        Toast.makeText(MainActivity.this,
                R.string.save_credential_failed + " " + errorCode + ":" + description,
                Toast.LENGTH_SHORT).show();
    }
});

用戶登出場景

1、使用一個Activity實例初始化CredentialClient,可以寫在Activity的onCreate方法中。

CredentialClient credentialClient = CredentialManager.getCredentialClient(this);

2、查詢是否存在可用的憑據。

List<AppIdentity> trustedAppList = new ArrayList<>();
trustedAppList.add(new AndroidAppIdentity("yourAppName", "yourAppPackageName", "yourAppCodeSigningCertHash"));
trustedAppList.add(new WebAppIdentity("youWebSiteName", "www.yourdomain.com"));
trustedAppList.add(new WebAppIdentity("youWebSiteName", "login.yourdomain.com"));
SharedCredentialFilter sharedCredentialFilter = SharedCredentialFilter.acceptTrustedApps(trustedAppList);
credentialClient.findCredential(sharedCredentialFilter, new CredentialCallback<List<Credential>>() {
    @Override
    public void onSuccess(List<Credential> credentials) {
        if (credentials.isEmpty()) {
            Toast.makeText(MainActivity.this, R.string.no_available_credential, Toast.LENGTH_SHORT).show();
        } else {
            for (Credential credential : credentials) {
                //可以對可用憑據進行進一步處理,包括:獲取憑據相關信息、獲取憑據內容、刪除
            }
        }
    }
 
    @Override
    public void onFailure(long errorCode, CharSequence description) {
        Toast.makeText(MainActivity.this, R.string.query_credential_failed, Toast.LENGTH_SHORT).show();
    }
});

3、調用deleteCredential刪除憑據,在CredentialCallback獲取結果。

credentialClient.deleteCredential(credential, new CredentialCallback<Void>() {
    @Override
    public void onSuccess(Void unused) {
        String hint = String.format(getResources().getString(R.string.delete_ok),
                credential.getUsername());
        Toast.makeText(MainActivity.this, hint, Toast.LENGTH_SHORT).show();
    }
 
    @Override
    public void onFailure(long errorCode, CharSequence description) {
        String hint = String.format(getResources().getString(R.string.delete_failed),
                description);
        Toast.makeText(MainActivity.this, hint, Toast.LENGTH_SHORT).show();
    }
});

憑據共用機制

通過API參數實現憑據共用

在調用saveCredential保存憑據時,您可以通過setSharedWith設置Credential對象的屬性實現憑據共用,最多支持共用給128個應用。

示例如下:

AndroidAppIdentity app1 = new AndroidAppIdentity("your android app name",
                "your android app package name", "3C:99:C3:....");
QuickAppIdentity app2 = new QuickAppIdentity("your quick app name",
                "your quick app package name", "DC:99:C4:....");
List<AppIdentity> sharedAppList = new ArrayList<>(); // 共用關係列表
sharedAppList.add(app1);
sharedAppList.add(app2);
Credential credential = new Credential("username", CredentialType.PASSWORD, true,
                "password".getBytes());
credential.setSharedWith(sharedAppList); // 設置共用關係
credentialClient.saveCredential(credential, new CredentialCallback<Void>() {
    @Override
    public void onSuccess(Void unused) {
        Toast.makeText(MainActivity.this,
                R.string.save_credential_ok,
                Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onFailure(long errorCode, CharSequence description) {
        Toast.makeText(MainActivity.this,
                R.string.save_credential_failed + " " + errorCode + ":" + description,
                Toast.LENGTH_SHORT).show();
    }
});

通過Digital Asset Links資源實現憑據共用

您可以在Android應用的AndroidManifest.xml中添加憑據共用關係,方法如下:

1、在AndroidManifest.xml的節點中添加以下內容:

<application>
           <meta-data
            android:name="asset_statements"
            android:value="@string/asset_statements" />
</application>
  1. 在res\values\strings.xml中添加以下內容:
<string name="asset_statements">your digital asset links statements</string>

Digital asset links statements是一個遵循Digital Asset links規範的JSON字元串,示例如下:

[{
                   "relation": ["delegate_permission/common.get_login_creds"],
                   "target": {
                            "namespace": "web",
                            "site": "https://developer.huawei.com" // 您的網站功能變數名稱
                   }
         },
         {
                   "relation": ["delegate_permission/common.get_login_creds"],
                   "target": {
                            "namespace": "android_app",
                            "package_name": "your android app package name",
                            "sha256_cert_fingerprints": [
                                     "F2:52:4D:..."
                            ]
                   }
         },
         {
                   "relation": ["delegate_permission/common.get_login_creds"],
                   "target": {
                            "namespace": "quick_app",
                            "package_name": "your quick app package name",
                            "sha256_cert_fingerprints": [
                                     "C3:68:9F:..."
                            ]
                   }
         }
]

relation屬性的值固定為["delegate_permission/common.get_login_creds"],表示把憑據共用給target屬性所描述的應用。

案例分享

航班管家和高鐵管家集成華為鑰匙環服務,為兩億用戶打造無縫登錄體驗。

瞭解更多詳情>>

訪問華為開發者聯盟官網
獲取開髮指導文檔
華為移動服務開源倉庫地址:GitHubGitee

關註我們,第一時間瞭解 HMS Core 最新技術資訊~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一:更新系統時間的方式 1、手動修改 通過相關工具來手動修改系統的時間。 2、自動同步 使用NTP自動同步系統時間。 二:手動修改系統時間 1、date工具 作用:顯示和設置系統時間 選項: -d <字元串> 顯示字元串所指的日期與時間,比如:"-1 day" 表示當前日期的前一天,必須要加雙引號 ...
  • OrientDB API v1.0.0(OrientDB 3.x) Gitee OrientDB介紹 OrientDB是一個開源的NoSQL資料庫管理系統,同時也是一款高性能的圖資料庫,支持ACID事務以及原子操作。 官網 圖資料庫介紹 圖資料庫是以點、邊為基礎存儲單元,以高效存儲、查詢圖數據為設計 ...
  • GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 作者: 楊延昭 文章來源:GreatSQL社區投稿 在進行資料庫備份的時候主要分為了邏輯備份和物理備份這兩種方式。在數據遷移和備份恢復中使用mysqld ...
  • MySQL 1. 索引 1.1 什麼是索引 索引是一種特殊的文件(InnoDB數據表上的索引是表空間的一個組成部分),它們包含著對數據表裡所有記錄的引用指針。 索引是一種數據結構。資料庫索引,是資料庫管理系統中一個排序的數據結構,以協助快速查詢、更新資料庫表中數據。索引的實現通常使用B樹及其變種B+ ...
  • 摘要:應用業務模型ABM(Application Business Model)是MSSI為客戶提供的統一模型管理服務。 本文分享自華為雲社區《【雲圖說】 | 第274期 MSSI之應用業務模型ABM,搭建業務與技術的數據治理橋梁》,作者:閱識風雲。 應用業務模型ABM(Application Bu ...
  • 摘要:SSRF (Server-Side Request Forgery,伺服器端請求偽造)是指由攻擊者構造請求,然後利用伺服器的漏洞以服務端的身份向內網發送請求對內網發起攻擊。 本文分享自華為雲社區《GaussDB(DWS)安全測試之SSRF漏洞》,作者: ACBD。 1. 什麼是SSRF漏洞 S ...
  • 這篇主要描述了B端令牌系統應用數據分表解決業務數據量增大,且存在的數據傾斜問題,主要面向的場景是一對多數據傾斜問題 ...
  • GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 作者: 葉金榮 文章來源:GreatSQL社區原創 1. MySQL 8.0數據字典有什麼變化 從MySQL 8.0開始,採用獨立表空間模式的每個Inn ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...