使用 Credentials API 请求自动让用户登录您的应用 并检索存储的用户凭据。
准备工作
创建 CredentialsClient 对象
要请求存储的凭据,您必须创建
CredentialsClient
,用于访问 Credentials API:
CredentialsClient mCredentialsClient;
// ...
mCredentialsApiClient = Credentials.getClient(this);
创建 CredentialRequest 对象
CredentialRequest
对象指定
。构建一个
使用 setPasswordLoginSupported
方法调用 CredentialRequest
基于密码的登录,以及用于联合身份验证的 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 登录,请创建一个 GoogleSignInClient
对象,
包含用户的 ID,然后使用该对象启动登录流程。基于密码
使用 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()
方法以提示用户
以选择账号。然后,从
activity 的 onActivityResult()
方法,方法是将 Credential.EXTRA_KEY
传递给
getParcelableExtra()
方法。
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
,
您可以视需要提示
用户可以选择最近使用过的登录信息,如电子邮件地址和
名称,并使用该信息自动填充表单的某些字段。
请参阅向用户提供登录提示
了解详情。
成功登录后,允许用户保存其凭据 以便在其所有设备上自动进行日后的身份验证。