ユーザーの認証情報を保存する

ユーザーがログイン、アカウントの作成、パスワードの変更に成功したら、アプリでの今後の認証を自動化するために、ユーザーが認証情報を保存できるようにします。

始める前に

Android Studio プロジェクトを構成する

認証情報を保存する

ユーザーのログイン情報を含む Credential オブジェクトを作成します。たとえば、ユーザーがパスワードを使って正常にログインした後に認証情報を保存できるようにするには、次のようにします。

Credential credential = new Credential.Builder(email)
        .setPassword(password)  // Important: only store passwords in this field.
                                // Android autofill uses this value to complete
                                // sign-in forms, so repurposing this field will
                                // likely cause errors.
        .build();

または、たとえばユーザーが Google アカウントでログインに成功したら、次の処理を行います。

GoogleSignInAccount gsa = signInTask.getResult();
Credential credential = new Credential.Builder(gsa.getEmail())
        .setAccountType(IdentityProviders.GOOGLE)
        .setName(gsa.getDisplayName())
        .setProfilePictureUri(gsa.getPhotoUrl())
        .build();

Smart Lock の保存ダイアログ

次に、CredentialsClient.save() を呼び出してユーザーの認証情報を保存します。CredentialsClient.save() の呼び出しがすぐに成功しない場合、認証情報が新しい可能性があります。その場合、ユーザーは保存リクエストを確認する必要があります。startResolutionForResult()ResolvableApiException を解決し、ユーザーに確認を求めるプロンプトを表示します。

ユーザーが認証情報を保存しないことを選択した場合、アプリのアカウントの認証情報を保存するよう求められます。ユーザーがオプトアウトした後に CredentialsClient.save() を呼び出すと、結果のステータス コードは CANCELED になります。ユーザーは後で Google 設定アプリの [Smart Lock for Passwords] セクションで有効にできます。次回に認証情報を保存するよう求めるメッセージを表示するには、ユーザーがすべてのアカウントで認証情報の保存を有効にする必要があります。

mCredentialsClient.save(credential).addOnCompleteListener(
        new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "SAVE: OK");
                    Toast.makeText(activity, "Credentials saved", Toast.LENGTH_SHORT).show();
                    return;
                }

                Exception e = task.getException();
                if (e instanceof ResolvableApiException) {
                    // Try to resolve the save request. This will prompt the user if
                    // the credential is new.
                    ResolvableApiException rae = (ResolvableApiException) e;
                    try {
                        rae.startResolutionForResult(this, RC_SAVE);
                    } catch (IntentSender.SendIntentException exception) {
                        // Could not resolve the request
                        Log.e(TAG, "Failed to send resolution.", exception);
                        Toast.makeText(activity, "Save failed", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    // Request has no resolution
                    Toast.makeText(activity, "Save failed", Toast.LENGTH_SHORT).show();
                }
            }
        });</pre>

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // ...

        if (requestCode == RC_SAVE) {
            if (resultCode == RESULT_OK) {
                Log.d(TAG, "SAVE: OK");
                Toast.makeText(this, "Credentials saved", Toast.LENGTH_SHORT).show();
            } else {
                Log.e(TAG, "SAVE: Canceled by user");
            }
        }

        // ...

    }

認証情報を保存したら、CredentialsClient.request() を呼び出して認証情報を取得します。

Android O 以降をターゲットとする場合

Android O 以降を搭載したデバイスで Smart Lock を使用してパスワード認証情報を保存すると、Smart Lock は可能な限り独自のダイアログではなく、ネイティブの自動入力確認ダイアログを使用します。(Google 自動入力を使用して保存された認証情報は、Smart Lock for Passwords と双方向で共有されます)。