保存済みの認証情報でユーザーのログインを行う

ワンタップ ログイン クライアントを使用して、ユーザーに取得権限をリクエストする ユーザーが以前にアプリへのログインに使用した認証情報のいずれかになります。これらの 認証情報には、Google アカウント、またはユーザー名とパスワードの組み合わせを使用できます。 Chrome、Android の自動入力、Smart Lock for Smart Lock for パスワード。

ワンタップのログイン UI

認証情報が正常に取得されたら、それを使用してスムーズに アプリにユーザーをログインさせます。

ユーザーが認証情報を保存していない場合は、UI は表示されず、 通常のログアウト操作が維持されます。

ワンタップ ログインを使用する場所

アプリでユーザーにログインを求める場合は、ログイン時にワンタップ UI を表示します。 表示されます。これは、「Google でログイン」機能をすでに持っている場合でも役立ちます。 ボタン: ワンタップ UI は、認証情報のみを表示するように構成できるため、 使用したことがあるユーザーには、使用頻度の低いユーザーに向けた 前回のログイン方法でログインできるようになり、誤って アプリで新しいアカウントを作成します。

アプリでログインがオプションの場合は、どのデバイスでもワンタップ ログインの使用を検討してください。 ログインすることでエクスペリエンスが向上します。たとえば、ユーザーが ログアウトした状態でアプリでコンテンツを閲覧します。ただし、コメントの投稿や 商品をショッピング カートに追加した場合、これは ワンタップでログインできます。

ログインのオプション アプリについても、ログイン画面でワンタップ ログインを使用する必要があります。 理由は上記のとおりです

始める前に

  • 次の説明に沿って、Google API Console プロジェクトと Android プロジェクトを設定します。 ワンタップ ログインを使ってみる
  • パスワード ベースのログインをサポートしている場合は、 自動入力(または Smart Lock for Passwords を使用する)を使用して、ユーザーが パスワード認証情報を入力します。

1. ワンタップ ログイン クライアントを構成する

ワンタップ ログイン クライアントを設定して、保存済みのパスワードを使用してユーザーがログインできるようにできます パスワード、保存した Google アカウント、またはいずれかです。(App Engine と Cloud Functions の両方をサポートすることが 新規ユーザーのワンタップ アカウントの作成と自動またはワンタップによるログインを有効にします なるべく多くのリピーターを対象にしてください)

アプリでパスワード ベースのログインを使用する場合は、setPasswordRequestOptions() を使用して以下を行います。 パスワード認証情報リクエストを有効にする。

アプリで Google ログインを使用する場合は、setGoogleIdTokenRequestOptions() を使用して以下を行います。 Google ID トークン リクエストを有効にして構成します。

  • サーバー クライアント ID を Google API で作成した ID に設定します。 コンソールで確認できます。これはサーバーのクライアント ID であり、 Android クライアント ID を入力します。

  • 承認済みアカウントでフィルタするようにクライアントを構成する。この機能を有効にすると、 オプションを使用する場合、One Tap クライアントは 過去に使用したことがある Google アカウント。そうすることで、ユーザーが すでにアカウントを持っているかどうかや ユーザーが誤って新しいアカウントを作成しないようにする 説明します。

  • 可能であればユーザーを自動的にログインさせる場合は、機能を有効にする setAutoSelectEnabled() で。自動ログインは、 次の条件を満たす必要があります

    • ユーザーはアプリの認証情報を 1 つだけ保存している。つまり、保存したパスワードまたは Google アカウントが 1 つだけある。
    • ユーザーが Google アカウント設定で自動ログインを無効にしていない。
  • 必須ではありませんが、メッセージにノンスを ログイン セキュリティを強化し、リプレイ攻撃を回避できます。使用 setNonce 各リクエストにノンスを含めるようにします。SafetyNet の ノンスを取得する に、ノンスの生成に関する提案や詳細情報を確認できます。

Java

public class YourActivity extends AppCompatActivity {
  // ...

  private SignInClient oneTapClient;
  private BeginSignInRequest signInRequest;

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState,
                       @Nullable PersistableBundle persistentState) {
      super.onCreate(savedInstanceState, persistentState);

      oneTapClient = Identity.getSignInClient(this);
      signInRequest = BeginSignInRequest.builder()
              .setPasswordRequestOptions(PasswordRequestOptions.builder()
                      .setSupported(true)
                      .build())
              .setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder()
                      .setSupported(true)
                      // Your server's client ID, not your Android client ID.
                      .setServerClientId(getString(R.string.default_web_client_id))
                      // Only show accounts previously used to sign in.
                      .setFilterByAuthorizedAccounts(true)
                      .build())
              // Automatically sign in when exactly one credential is retrieved.
              .setAutoSelectEnabled(true)
              .build();
      // ...
  }
  // ...
}

Kotlin

class YourActivity : AppCompatActivity() {
    // ...

    private lateinit var oneTapClient: SignInClient
    private lateinit var signInRequest: BeginSignInRequest

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        oneTapClient = Identity.getSignInClient(this)
        signInRequest = BeginSignInRequest.builder()
            .setPasswordRequestOptions(BeginSignInRequest.PasswordRequestOptions.builder()
                .setSupported(true)
                .build())
            .setGoogleIdTokenRequestOptions(
                BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                    .setSupported(true)
                    // Your server's client ID, not your Android client ID.
                    .setServerClientId(getString(R.string.your_web_client_id))
                    // Only show accounts previously used to sign in.
                    .setFilterByAuthorizedAccounts(true)
                    .build())
            // Automatically sign in when exactly one credential is retrieved.
            .setAutoSelectEnabled(true)
            .build()
        // ...
    }
    // ...
}

2. ログインしているユーザーを確認する

ログインしているユーザーやログアウトしたユーザーがアクティビティを使用できる場合は、 ワンタップ ログイン UI を表示する前に、ユーザーのステータスを確認してください。

また、ユーザーが使用を拒否したかどうかも追跡する必要があります。 ワンタップでログインするには、メッセージを閉じるか、メッセージの外側をタップします。これにより、 プロパティのブール値のプロパティと同じくらいシンプルにすることです。 (下記のワンタップ UI の表示を停止するをご覧ください)。

3. ワンタップ ログイン UI を表示する

ユーザーがログインしておらず、ワンタップ ログインの使用をすでに拒否していない場合、 クライアント オブジェクトの beginSignIn() メソッドを呼び出して、リスナーを Task を返します。通常、アプリはアクティビティの onCreate() メソッドでこれを行います。 または画面の遷移後に行うことをおすすめします。

ユーザーが保存済みイベントがある場合は、ワンタップ クライアントがサクセス リスナーを呼び出します。 認証情報を取得できます。成功リスナーで、以下からペンディング インテントを取得します。 Task の結果を startIntentSenderForResult() に渡して、 ワンタップのログイン UI。

ユーザーが保存済みの認証情報を持っていない場合、ワンタップ クライアントは 使用します。この場合は何もする必要はありません。そのまま続行できます。 アプリのログアウト状態を表示します。ただし、ワンタップをサポートしている場合は、 登録したら ここからフローを始め 体験できますワンタップで新しいアカウントを作成するをご覧ください。

Java

oneTapClient.beginSignIn(signUpRequest)
        .addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
            @Override
            public void onSuccess(BeginSignInResult result) {
                try {
                    startIntentSenderForResult(
                            result.getPendingIntent().getIntentSender(), REQ_ONE_TAP,
                            null, 0, 0, 0);
                } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
                }
            }
        })
        .addOnFailureListener(this, new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // No saved credentials found. Launch the One Tap sign-up flow, or
                // do nothing and continue presenting the signed-out UI.
                Log.d(TAG, e.getLocalizedMessage());
            }
        });

Kotlin

oneTapClient.beginSignIn(signInRequest)
    .addOnSuccessListener(this) { result ->
        try {
            startIntentSenderForResult(
                result.pendingIntent.intentSender, REQ_ONE_TAP,
                null, 0, 0, 0, null)
        } catch (e: IntentSender.SendIntentException) {
            Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
        }
    }
    .addOnFailureListener(this) { e ->
        // No saved credentials found. Launch the One Tap sign-up flow, or
        // do nothing and continue presenting the signed-out UI.
        Log.d(TAG, e.localizedMessage)
    }

4. ユーザーの応答を処理する

ワンタップのログイン メッセージに対するユーザーの回答がアプリに報告されます アクティビティの onActivityResult() メソッドを使用します。ユーザーがログインを選択した場合 保存された認証情報になりますユーザーがログインを拒否した場合は、次のいずれかの対応を行います。 ワンタップ UI を閉じるか、その外側をタップして、 コード RESULT_CANCELED。アプリは両方の可能性に対応する必要があります。

取得した認証情報でログインする

ユーザーがアプリと認証情報を共有することを選択した場合は、次の方法で認証情報を取得できます。 インテント データを onActivityResult() からワンタップ クライアントの getSignInCredentialFromIntent() メソッドを使用します。認証情報は非 null となります。 ユーザーが Google アカウントの認証情報を次のユーザーと共有した場合は、googleIdToken プロパティ ユーザーが保存したパスワードを共有した場合は、null 以外の password プロパティを返します。

認証情報を使用してアプリのバックエンドを認証します。

  • ユーザー名とパスワードのペアを取得した場合は、それらを使用して同じ ユーザーが手動で入力した場合と同じように処理できます。
  • Google アカウントの認証情報を取得した場合は、ID トークンを使用して認証します。 確認しますリプレイを回避するためにノンスを使用することを選択した場合 攻撃によってバックエンド サーバーのレスポンス値がチェックされます。詳しくは、 ID トークンを使用してバックエンドで認証する

Java

public class YourActivity extends AppCompatActivity {

  // ...
  private static final int REQ_ONE_TAP = 2;  // Can be any integer unique to the Activity.
  private boolean showOneTapUI = true;
  // ...

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

      switch (requestCode) {
          case REQ_ONE_TAP:
              try {
                  SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(data);
                  String idToken = credential.getGoogleIdToken();
                  String username = credential.getId();
                  String password = credential.getPassword();
                  if (idToken !=  null) {
                      // Got an ID token from Google. Use it to authenticate
                      // with your backend.
                      Log.d(TAG, "Got ID token.");
                  } else if (password != null) {
                      // Got a saved username and password. Use them to authenticate
                      // with your backend.
                      Log.d(TAG, "Got password.");
                  }
              } catch (ApiException e) {
                  // ...
              }
              break;
      }
  }
}

Kotlin

class YourActivity : AppCompatActivity() {

    // ...
    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private var showOneTapUI = true
    // ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
             REQ_ONE_TAP -> {
                try {
                    val credential = oneTapClient.getSignInCredentialFromIntent(data)
                    val idToken = credential.googleIdToken
                    val username = credential.id
                    val password = credential.password
                    when {
                        idToken != null -> {
                            // Got an ID token from Google. Use it to authenticate
                            // with your backend.
                            Log.d(TAG, "Got ID token.")
                        }
                        password != null -> {
                            // Got a saved username and password. Use them to authenticate
                            // with your backend.
                            Log.d(TAG, "Got password.")
                        }
                        else -> {
                            // Shouldn't happen.
                            Log.d(TAG, "No ID token or password!")
                        }
                    }
                } catch (e: ApiException) {
                    // ...
                }
            }
        }
    }
    // ...
}

ワンタップ UI の表示を停止する

ユーザーがログインを拒否した場合、getSignInCredentialFromIntent() への呼び出し ステータス コード CommonStatusCodes.CANCELED とともに ApiException がスローされます。 このような場合は、ワンタップによるログイン UI を一時的に無効にして、 プロンプトを繰り返し表示して ユーザーをイライラさせないことです次の例では、以下を行います。 Activity にプロパティを設定することで、アクティビティに ユーザーにワンタップ ログインを提供する。必要に応じて SharedPreferences または他のメソッドを使用します。

ワンタップでのログイン メッセージに対して、独自のレート制限を実装することが重要です。 キャンセルせず、ユーザーが連続して複数のプロンプトをキャンセルした場合、ワンタップ クライアントは 今後 24 時間はユーザーに表示されません。

Java

public class YourActivity extends AppCompatActivity {

  // ...
  private static final int REQ_ONE_TAP = 2;  // Can be any integer unique to the Activity.
  private boolean showOneTapUI = true;
  // ...

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

      switch (requestCode) {
          case REQ_ONE_TAP:
              try {
                  // ...
              } catch (ApiException e) {
                  switch (e.getStatusCode()) {
                      case CommonStatusCodes.CANCELED:
                          Log.d(TAG, "One-tap dialog was closed.");
                          // Don't re-prompt the user.
                          showOneTapUI = false;
                          break;
                      case CommonStatusCodes.NETWORK_ERROR:
                          Log.d(TAG, "One-tap encountered a network error.");
                          // Try again or just ignore.
                          break;
                      default:
                          Log.d(TAG, "Couldn't get credential from result."
                                  + e.getLocalizedMessage());
                          break;
                  }
              }
              break;
      }
  }
}

Kotlin

class YourActivity : AppCompatActivity() {

    // ...
    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private var showOneTapUI = true
    // ...

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
            REQ_ONE_TAP -> {
                try {
                    // ...
                } catch (e: ApiException) {
                    when (e.statusCode) {
                        CommonStatusCodes.CANCELED -> {
                            Log.d(TAG, "One-tap dialog was closed.")
                            // Don't re-prompt the user.
                            showOneTapUI = false
                        }
                        CommonStatusCodes.NETWORK_ERROR -> {
                            Log.d(TAG, "One-tap encountered a network error.")
                            // Try again or just ignore.
                        }
                        else -> {
                            Log.d(TAG, "Couldn't get credential from result." +
                                " (${e.localizedMessage})")
                        }
                    }
                }
            }
        }
    }
    // ...
}

5. ログアウトを処理する

ユーザーがアプリからログアウトしたら、ワンタップ クライアントの signOut() メソッドを呼び出します。 signOut() を呼び出すと、ユーザーが再度ログインするまで自動ログインが無効になります。

自動ログインを使用していない場合でも、この手順は重要です。 ユーザーがアプリからログアウトしたときに、そのアプリの認証状態が 使用している Play 開発者サービス API もリセットされます。

次のステップ

Google 認証情報を取得するようにワンタップ クライアントを設定した場合、アプリは ユーザーの ID トークンを取得できるようになります。Google アカウント。学習 これらのトークンをバックエンドで使用する方法を確認します。

Google ログインをサポートしている場合は、ワンタップ クライアントを使用して アプリをスムーズに作成できます