Google のユーザーデータへのアクセスを承認する

認証は、ユーザーが誰であるかを特定するもので、通常はユーザー登録またはログインと呼ばれます。認可は、データまたはリソースへのアクセスを許可または拒否するプロセスです。たとえば、アプリがユーザーの Google ドライブにアクセスするための同意をユーザーに求める場合です。

認証と認可の呼び出しは、アプリのニーズに基づいて 2 つの別個のフローにする必要があります。

アプリに Google API のデータを利用できる機能があるものの、アプリのコア機能の一部として必須ではない場合は、API データにアクセスできない場合を適切に処理できるようにアプリを設計する必要があります。たとえば、ユーザーがドライブへのアクセスを許可していない場合、最近保存したファイルのリストを非表示にできます。

Google API にアクセスするために必要なスコープへのアクセス権は、ユーザーが特定の API へのアクセスを必要とする操作を行った場合にのみリクエストする必要があります。たとえば、ユーザーが [ドライブに保存] ボタンをタップするたびに、ユーザーのドライブにアクセスする権限をリクエストする必要があります。

認証と認可を分離することで、新規ユーザーに負担をかけたり、特定の権限を求められる理由についてユーザーが混乱したりすることを防ぐことができます。

認証には、Credential Manager API を使用することをおすすめします。Google が保存したユーザーデータへのアクセスを必要とするアクションを承認するには、AuthorizationClient の使用をおすすめします。

プロジェクトを設定する

  1. でプロジェクトを開くか、まだ作成していない場合はプロジェクトを作成します。
  2. で、すべての情報が完全かつ正確であることを確認します。
    1. アプリに正しいアプリ名、アプリのロゴ、アプリのホームページが割り当てられていることを確認します。これらの値は、登録時の [Google でログイン] の同意画面と [サードパーティ製のアプリとサービス] 画面でユーザーに表示されます。
    2. アプリのプライバシー ポリシーと利用規約の URL を指定していることを確認します。
  3. で、アプリの Android クライアント ID を作成します(まだ作成していない場合)。アプリのパッケージ名と SHA-1 署名を指定する必要があります。
    1. に移動します。
    2. [クライアントを作成] をクリックします。
    3. アプリケーションの種類として [Android] を選択します。
  4. で、まだ作成していない場合は、新しい「ウェブ アプリケーション」クライアント ID を作成します。[承認済みの JavaScript 生成元] と [承認済みのリダイレクト URI] のフィールドは、今のところ無視してかまいません。このクライアント ID は、バックエンド サーバーが Google の認証サービスと通信する際に、バックエンド サーバーを識別するために使用されます。
    1. に移動します。
    2. [クライアントを作成] をクリックします。
    3. [ウェブ アプリケーション] タイプを選択します。

依存関係の宣言

モジュールの build.gradle ファイルで、Google Identity Services ライブラリの最新バージョンを使用して依存関係を宣言します。

dependencies {
  // ... other dependencies

  implementation "com.google.android.gms:play-services-auth:<latest version>"
}

ユーザー アクションに必要な権限をリクエストする

ユーザーが追加のスコープを必要とするアクションを実行するたびに、AuthorizationClient.authorize() を呼び出します。

たとえば、ユーザーがドライブ アプリのストレージへのアクセスを必要とする操作を行った場合は、次の手順を行います。

List<Scopes> requestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA);
AuthorizationRequest authorizationRequest = AuthorizationRequest.builder().setRequestedScopes(requestedScopes).build();
Identity.getAuthorizationClient(this)
        .authorize(authorizationRequest)
        .addOnSuccessListener(
            authorizationResult -> {
              if (authorizationResult.hasResolution()) {
                    // Access needs to be granted by the user
                PendingIntent pendingIntent = authorizationResult.getPendingIntent();
                try {
startIntentSenderForResult(pendingIntent.getIntentSender(),
REQUEST_AUTHORIZE, null, 0, 0, 0, null);
                } catch (IntentSender.SendIntentException e) {
                Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage());
                }
              } else {
            // Access already granted, continue with user action
                saveToDriveAppFolder(authorizationResult);
              }
            })
        .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));

アクティビティの onActivityResult コールバックで、必要な権限が正常に取得されたかどうかを確認し、取得された場合はユーザー アクションを実行できます。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (requestCode == MainActivity.REQUEST_AUTHORIZE) {
    AuthorizationResult authorizationResult = Identity.getAuthorizationClient(this).getAuthorizationResultFromIntent(data);
    saveToDriveAppFolder(authorizationResult);
  }
}

サーバーサイドで Google API にアクセスする場合は、AuthorizationResult の getServerAuthCode() メソッドを呼び出して認証コードを取得し、バックエンドに送信してアクセス トークンと更新トークンに交換できます。