使用 Credentials API 请求和检索为用户存储的凭据,以便自动让用户登录您的应用。
准备工作
创建 CredentialsClient 对象
如需请求存储的凭据,您必须创建 CredentialsClient
实例来访问 Credentials API:
CredentialsClient mCredentialsClient;
// ...
mCredentialsApiClient = Credentials.getClient(this);
创建 CredentialRequest 对象
CredentialRequest
对象指定您要从中请求凭据的登录系统。构建 CredentialRequest
。对于基于密码的登录,使用 setPasswordLoginSupported
方法;对于联合登录服务(如 Google 登录),使用 setAccountTypes()
方法。
mCredentialRequest = new CredentialRequest.Builder()
.setPasswordLoginSupported(true)
.setAccountTypes(IdentityProviders.GOOGLE, IdentityProviders.TWITTER)
.build();
使用 IdentityProviders
中定义的常量来指定常用的登录提供方。对于其他登录提供方,使用可唯一标识提供方的任何字符串。您必须使用与检索凭据相同的提供方标识符来存储凭据。
请求存储的凭据
创建 CredentialsClient
和 CredentialRequest
对象后,请将请求对象传递给 CredentialsClient.request()
方法,以请求为应用存储的凭据。
mCredentialsClient.request(mCredentialRequest).addOnCompleteListener(
new OnCompleteListener<CredentialRequestResponse>() {
@Override
public void onComplete(@NonNull Task<CredentialRequestResponse> task) {
if (task.isSuccessful()) {
// See "Handle successful credential requests"
onCredentialRetrieved(task.getResult().getCredential());
return;
}
// See "Handle unsuccessful and incomplete credential requests"
// ...
}
});
定义一个回调,以使用 addOnCompleteListener()
方法处理成功和失败的请求。
处理成功的凭据请求
凭据请求成功后,使用生成的 Credential
对象完成用户登录应用。使用 getAccountType()
方法确定检索到的凭据的类型,然后完成相应的登录过程。例如,对于 Google 登录,请创建一个包含用户 ID 的 GoogleSignInClient
对象,然后使用该对象启动登录流程。对于基于密码的登录,请使用 Credential 对象中的用户 ID 和密码来完成应用的登录流程。
private void onCredentialRetrieved(Credential credential) {
String accountType = credential.getAccountType();
if (accountType == null) {
// Sign the user in with information from the Credential.
signInWithPassword(credential.getId(), credential.getPassword());
} else if (accountType.equals(IdentityProviders.GOOGLE)) {
// The user has previously signed in with Google Sign-In. Silently
// sign in the user with the same ID.
// See https://developers.google.com/identity/sign-in/android/
GoogleSignInOptions gso =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
GoogleSignInClient signInClient = GoogleSignIn.getClient(this, gso);
Task<GoogleSignInAccount> task = signInClient.silentSignIn();
// ...
}
}
处理多个已保存的凭据
当需要用户输入选择凭据时,request()
任务将失败并显示 ResolvableApiException
。检查 getStatusCode()
是否返回 RESOLUTION_REQUIRED
,并调用异常的 startResolutionForResult()
方法来提示用户选择帐号。然后,通过将 Credential.EXTRA_KEY
传递给 getParcelableExtra()
方法,从 activity 的 onActivityResult()
方法中检索用户选择的凭据。
mCredentialsClient.request(request).addOnCompleteListener( new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { // ... return; } Exception e = task.getException(); if (e instanceof ResolvableApiException) { // This is most likely the case where the user has multiple saved // credentials and needs to pick one. This requires showing UI to // resolve the read request. ResolvableApiException rae = (ResolvableApiException) e; resolveResult(rae, RC_READ); } else if (e instanceof ApiException) { // The user must create an account or sign in manually. Log.e(TAG, "Unsuccessful credential request.", e); ApiException ae = (ApiException) e; int code = ae.getStatusCode(); // ... } } });
private void resolveResult(ResolvableApiException rae, int requestCode) {
try {
rae.startResolutionForResult(MainActivity.this, requestCode);
mIsResolving = true;
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Failed to send resolution.", e);
hideProgress();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// ...
if (requestCode == RC_READ) {
if (resultCode == RESULT_OK) {
Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
onCredentialRetrieved(credential);
} else {
Log.e(TAG, "Credential Read: NOT OK");
Toast.makeText(this, "Credential Read Failed", Toast.LENGTH_SHORT).show();
}
}
// ...
}
如果未找到存储的凭据,用户必须创建帐号或手动登录。如果 getStatusCode()
返回 SIGN_IN_REQUIRED
,您可以选择提示用户选择最近用过的登录信息(例如电子邮件地址和姓名),并使用该信息自动填充表单的某些字段,从而加快注册和登录流程。如需了解详情,请参阅向用户提供登录提示。
成功登录后,允许用户保存其凭据,以便将来在其所有设备上自动进行身份验证。