Credentials API を使用してユーザーを自動的にアプリにログインし、保存されている認証情報をリクエストして取得します。
始める前に
CredentialsClient オブジェクトを作成する
保存されている認証情報をリクエストするには、CredentialsClient
のインスタンスを作成して Credentials API にアクセスする必要があります。
CredentialsClient mCredentialsClient;
// ...
mCredentialsApiClient = Credentials.getClient(this);
CredentialRequest オブジェクトを作成する
CredentialRequest
オブジェクトは、認証情報をリクエストするログイン システムを指定します。パスワード ベースのログインには setPasswordLoginSupported
メソッドを使用し、Google ログインなどのフェデレーション ログイン サービスには setAccountTypes()
メソッドを使用して、CredentialRequest
を作成します。
mCredentialRequest = new CredentialRequest.Builder()
.setPasswordLoginSupported(true)
.setAccountTypes(IdentityProviders.GOOGLE, IdentityProviders.TWITTER)
.build();
IdentityProviders
で定義されている定数を使用して、よく使用されるログイン プロバイダを指定します。他のログイン プロバイダの場合は、プロバイダを一意に識別する任意の文字列を使用します。認証情報の保存には、認証情報の取得に使用したものと同じプロバイダ ID を使用する必要があります。
保存されている認証情報をリクエストする
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
オブジェクトを作成し、そのオブジェクトを使用してログインフローを開始します。パスワード ベースのログインの場合は、認証情報オブジェクトから取得したユーザーの 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()
メソッドに渡して、ユーザーが選択した認証情報をアクティビティの 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
が返された場合は、必要に応じて登録プロセスとログイン プロセスを迅速化できます。これにより、最近使用したログイン情報(メールアドレスや名前など)を選択するようユーザーに促し、フォームの一部のフィールドにその情報を自動的に入力できます。
詳しくは、ユーザーにログインのヒントを提供するをご覧ください。
ログインが成功したら、ユーザーが認証情報を保存できるようにして、すべてのデバイスでの今後の認証を自動化できるようにします。