近些年來,隨著手機技術迭代更新越來越快,用戶更換手機的周期也在縮短,在這樣的背景下,開發者不得不面臨以下問題: 同一開發者旗下常常有多個安卓應用和多形態應用(快應用和Web應用),用戶更換一個新的設備(手機或平板)後,在新設備上登錄各應用時每次都需要重覆輸入帳號和密碼,導致用戶在登錄階段流失率增加, ...
近些年來,隨著手機技術迭代更新越來越快,用戶更換手機的周期也在縮短,在這樣的背景下,開發者不得不面臨以下問題:
同一開發者旗下常常有多個安卓應用和多形態應用(快應用和Web應用),用戶更換一個新的設備(手機或平板)後,在新設備上登錄各應用時每次都需要重覆輸入帳號和密碼,導致用戶在登錄階段流失率增加,同時開發者還需要承擔額外的簡訊成本(如用戶使用簡訊登錄)。
華為HMS Core鑰匙環服務(Keyring)提供憑據管理介面(Credentials Management API),為Android手機、平板提供用戶登錄憑據存儲和跨應用、跨應用形態、跨設備共用的能力。
鑰匙環服務提供了Android API、Web 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>
- 在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屬性所描述的應用。
案例分享
航班管家和高鐵管家集成華為鑰匙環服務,為兩億用戶打造無縫登錄體驗。
瞭解更多詳情>>
訪問華為開發者聯盟官網
獲取開髮指導文檔
華為移動服務開源倉庫地址:GitHub、Gitee
關註我們,第一時間瞭解 HMS Core 最新技術資訊~