近些年來,隨著手機技術迭代更新越來越快,使用者更換手機的週期也在縮短,在這樣的背景下,開發者不得不面臨以下問題:
同一開發者旗下常常有多個安卓應用和多形態應用(快應用和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<T>獲取結果。
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>節點中新增以下內容:
<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 最新技術資訊~