Google は、黒人コミュニティのための人種的公平の促進に取り組んでいます。詳細をご覧ください。

AndroidでOpenIDConnectを使用して認証する

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

IdentityPlatformを使用したFirebaseAuthenticationにアップグレードした場合は、選択したOpenID Connect(OIDC)準拠のプロバイダーを使用してFirebaseでユーザーを認証できます。これにより、FirebaseでネイティブにサポートされていないIDプロバイダーを使用できるようになります。

あなたが始める前に

OIDCプロバイダーを使用してユーザーにサインインするには、最初にプロバイダーからいくつかの情報を収集する必要があります。

  • クライアントID :アプリを識別するプロバイダーに固有の文字列。プロバイダーは、サポートするプラットフォームごとに異なるクライアントIDを割り当てる場合があります。これは、プロバイダーによって発行されたIDトークンのaudクレームの値の1つです。

  • クライアントシークレット:プロバイダーがクライアントIDの所有権を確認するために使用するシークレット文字列。クライアントIDごとに、一致するクライアントシークレットが必要になります。 (この値は、認証コードフローを使用している場合にのみ必要です。これを強くお勧めします。)

  • 発行者:プロバイダーを識別する文字列。この値は、/。 /.well-known/openid-configurationを追加すると、プロバイダーのOIDC検出ドキュメントの場所となるURLである必要があります。たとえば、発行者がhttps://auth.example.comの場合、検出ドキュメントはhttps://auth.example.com/.well-known/openid-configurationで利用可能である必要があります。

上記の情報を入手したら、FirebaseプロジェクトのサインインプロバイダーとしてOpenIDConnectを有効にします。

  1. AndroidプロジェクトにFirebaseを追加します

  2. IdentityPlatformを使用したFirebaseAuthenticationにアップグレードしていない場合は、アップグレードしてください。 OpenID Connect認証は、アップグレードされたプロジェクトでのみ使用できます。

  3. Firebaseコンソールの[ログインプロバイダー]ページで、[新しいプロバイダーの追加]をクリックし、[ OpenIDConnect ]をクリックします。

  4. 承認コードフローを使用するか、暗黙的な許可フローを使用するかを選択します。

    プロバイダーがサポートしている場合は、常にコードフローを使用する必要があります。暗黙のフローは安全性が低く、使用することは強くお勧めしません。

  5. このプロバイダーに名前を付けます。生成されたプロバイダーIDに注意してください: oidc.example-providerようなもの。アプリにログインコードを追加するときに、このIDが必要になります。

  6. クライアントIDとクライアントシークレット、およびプロバイダーの発行者文字列を指定します。これらの値は、プロバイダーが割り当てた値と正確に一致する必要があります。

  7. 変更を保存します。

FirebaseSDKを使用してログインフローを処理する

Androidアプリを構築している場合、OIDCプロバイダーを使用してFirebaseでユーザーを認証する最も簡単な方法は、FirebaseAndroidSDKでログインフロー全体を処理することです。

Firebase Android SDKでログインフローを処理するには、次の手順に従います。

  1. プロバイダーのIDを持つビルダーを使用してOAuthProviderのインスタンスを構築します

    Kotlin+KTX

    val providerBuilder = OAuthProvider.newBuilder("oidc.example-provider")
    

    Java

    OAuthProvider.Builder providerBuilder = OAuthProvider.newBuilder("oidc.example-provider");
    
  2. オプション:OAuthリクエストで送信する追加のカスタムOAuthパラメーターを指定します。

    Kotlin+KTX

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com")
    

    Java

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com");
    

    サポートされているパラメーターについては、OIDCプロバイダーに確認してください。 setCustomParameters()を使用してFirebaseに必要なパラメータを渡すことはできないことに注意してください。これらのパラメーターは、 client_idresponse_typeredirect_uristatescope 、およびresponse_modeです。

  3. オプション:認証プロバイダーに要求する基本プロファイル以外の追加のOAuth2.0スコープを指定します。

    Kotlin+KTX

    val scopes = arrayListOf("mail.read", "calendars.read")
    providerBuilder.setScopes(scopes)
    

    Java

    List<String> scopes =
        new ArrayList<String>() {
          {
            add("mail.read");
            add("calendars.read");
          }
        };
    providerBuilder.setScopes(scopes);
    

    使用するスコープについては、OIDCプロバイダーに確認してください。

  4. OAuthプロバイダーオブジェクトを使用してFirebaseで認証します。他のFirebaseAuth操作とは異なり、これはカスタムChromeタブをポップアップすることでUIを制御することに注意してください。そのため、操作がUIを開始するとすぐに切り離されるため、アタッチするOnSuccessListenerおよびOnFailureListenerでアクティビティを参照しないでください。

    最初に、すでに応答を受け取っているかどうかを確認する必要があります。この方法でサインインすると、アクティビティがバックグラウンドで実行されます。つまり、サインインフロー中にシステムによってアクティビティを再利用できます。これが発生した場合にユーザーに再試行させないようにするために、結果がすでに存在するかどうかを確認する必要があります。

    保留中の結果があるかどうかを確認するには、 getPendingAuthResultを呼び出します。

    Kotlin+KTX

    val pendingResultTask = FirebaseAuth.getInstance().pendingAuthResult
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
            .addOnSuccessListener { authResult ->
                // User is signed in.
    
                // IdP data available in
                //   authResult.additionalUserInfo.profile
    
                // The OAuth access token and ID token can also be retrieved:
                val credential = authResult.credential
                if (credential !is OAuthCredential)
                    return@addOnSuccessListener
                val accessToken = credential.accessToken
                val idToken = credential.idToken
            }
            .addOnFailureListener { e ->
                // Handle failure.
            }
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }
    

    Java

    Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
    if (pendingResultTask != null) {
      // There's something already here! Finish the sign-in for your user.
      pendingResultTask
          .addOnSuccessListener(
              new OnSuccessListener<AuthResult>() {
                @Override
                public void onSuccess(AuthResult authResult) {
                  // User is signed in.
                  // IdP data available in
                  // authResult.getAdditionalUserInfo().getProfile().
                  // The OAuth access token can also be retrieved:
                  // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                  // The OAuth ID token can also be retrieved:
                  // ((OAuthCredential)authResult.getCredential()).getIdToken().
                }
              })
          .addOnFailureListener(
              new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                  // Handle failure.
                }
              });
    } else {
      // There's no pending result so you need to start the sign-in flow.
      // See below.
    }
    

    サインインフローを開始するには、 startActivityForSignInWithProviderを呼び出します。

    Kotlin+KTX

    FirebaseAuth.getInstance()
        .startActivityForSignInWithProvider(/* activity= */ this, providerBuilder.build())
        .addOnSuccessListener { authResult ->
            // User is signed in.
    
            // IdP data available in:
            //    authResult.additionalUserInfo.profile
    
            // The OAuth access token and ID token can also be retrieved:
            val credential = authResult.credential
            if (credential !is OAuthCredential)
                return@addOnSuccessListener
            val accessToken = credential.accessToken
            val idToken = credential.idToken
        }
        .addOnFailureListener { e ->
            // Handle failure.
        }
    

    Java

    firebaseAuth
        .startActivityForSignInWithProvider(/* activity= */ this, providerBuilder.build())
        .addOnSuccessListener(
            new OnSuccessListener<AuthResult>() {
              @Override
              public void onSuccess(AuthResult authResult) {
                // User is signed in.
                // IdP data available in
                // authResult.getAdditionalUserInfo().getProfile().
                // The OAuth access token can also be retrieved:
                // authResult.getCredential().getAccessToken().
                // The OAuth ID token can also be retrieved:
                // authResult.getCredential().getIdToken().
              }
            })
        .addOnFailureListener(
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Handle failure.
              }
            });
    
  5. 上記の例はサインインフローに焦点を当てていますが、startActivityForLinkWithProviderを使用してstartActivityForLinkWithProviderプロバイダーを既存のユーザーにリンクすることもできます。たとえば、複数のプロバイダーを同じユーザーにリンクして、どちらかでサインインできるようにすることができます。

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = FirebaseAuth.getInstance().currentUser
    
    firebaseUser
        ?.startActivityForLinkWithProvider(/* activity= */ this, providerBuilder.build())
        ?.addOnSuccessListener { authResult ->
            // OIDC credential is linked to the current user.
    
            // IdP data available in:
            //   authResult.additionalUserInfo.profile
    
            // The OAuth access token and ID token can also be retrieved:
            val credential = authResult.credential
            if (credential !is OAuthCredential)
                return@addOnSuccessListener
            val accessToken = credential.accessToken
            val idToken = credential.idToken
        }
        ?.addOnFailureListener { e ->
            // Handle failure.
        }
    

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
        .startActivityForLinkWithProvider(/* activity= */ this, provider.build())
        .addOnSuccessListener(
            new OnSuccessListener<AuthResult>() {
              @Override
              public void onSuccess(AuthResult authResult) {
                // Credential is linked to the current user.
                // IdP data available in
                // authResult.getAdditionalUserInfo().getProfile().
                // The OAuth access token can also be retrieved:
                // authResult.getCredential().getAccessToken().
                // The OAuth ID token can also be retrieved:
                // authResult.getCredential().getIdToken().
              }
            })
        .addOnFailureListener(
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Handle failure.
              }
            });
    
  6. 同じパターンをstartActivityForReauthenticateWithProviderで使用できます。これを使用して、最近のログインを必要とする機密性の高い操作の新しい資格情報を取得できます。

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = FirebaseAuth.getInstance().currentUser
    
    firebaseUser
        ?.startActivityForReauthenticateWithProvider(/* activity= */ this, providerBuilder.build())
        ?.addOnSuccessListener {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
        }
        ?.addOnFailureListener {
            // Handle failure.
        }
    

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
        .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
        .addOnSuccessListener(
            new OnSuccessListener<AuthResult>() {
              @Override
              public void onSuccess(AuthResult authResult) {
                // User is re-authenticated with fresh tokens and
                // should be able to perform sensitive operations
                // like account deletion and email or password
                // update.
              }
            })
        .addOnFailureListener(
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Handle failure.
              }
            });
    

サインインフローを手動で処理する

アプリにOpenIDConnectサインインフローを既に実装している場合は、IDトークンを直接使用してFirebaseで認証できます。

Kotlin+KTX

      val credential = OAuthProvider
          .newCredentialBuilder("oidc.example-provider")  // As registered in Firebase console.
          .setIdToken(idToken)  // ID token from OpenID Connect flow.
          .build()
      FirebaseAuth.getInstance()
          .signInWithCredential(credential)
          .addOnSuccessListener { authResult ->
              // User is signed in.

              // IdP data available in:
              //    authResult.additionalUserInfo.profile
          }
          .addOnFailureListener { e ->
              // Handle failure.
          }

Java

AuthCredential credential = OAuthProvider
        .newCredentialBuilder("oidc.example-provider")  // As registered in Firebase console.
        .setIdToken(idToken)  // ID token from OpenID Connect flow.
        .build();
FirebaseAuth.getInstance()
        .signInWithCredential(credential)
        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                // User is signed in.

                // IdP data available in:
                //    authResult.getAdditionalUserInfo().getProfile()
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // Handle failure.
            }
        });

次のステップ

ユーザーが初めてサインインすると、新しいユーザーアカウントが作成され、ユーザーがサインインした資格情報(つまり、ユーザー名とパスワード、電話番号、または認証プロバイダー情報)にリンクされます。この新しいアカウントはFirebaseプロジェクトの一部として保存され、ユーザーのログイン方法に関係なく、プロジェクト内のすべてのアプリでユーザーを識別するために使用できます。

  • アプリでは、 FirebaseUserオブジェクトからユーザーの基本的なプロファイル情報を取得できます。ユーザーの管理を参照してください。

  • FirebaseRealtimeデータベースとCloudStorageのセキュリティルールでは、ログインしたユーザーの一意のユーザーIDをauth変数から取得し、それを使用してユーザーがアクセスできるデータを制御できます。

認証プロバイダーのクレデンシャルを既存のユーザーアカウントにリンクすることで、ユーザーが複数の認証プロバイダーを使用してアプリにサインインできるようにすることができます。

ユーザーをサインアウトするには、 signOutを呼び出します。

Java

FirebaseAuth.getInstance().signOut();

Kotlin+KTX

Firebase.auth.signOut()