OIDC を使用したユーザーのログイン

このドキュメントでは、Identity Platform を使用して、OpenID Connect(OIDC)プロバイダでユーザーをログインさせる方法を説明します。

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Identity Platform を有効にして、クライアント SDK をアプリに追加します。その方法については、クイックスタートをご覧ください。

プロバイダの構成

  1. Google Cloud コンソールで [ID プロバイダ] ページに移動します。
    [ID プロバイダ] ページに移動

  2. [プロバイダを追加] をクリックし、リストから [OpenID Connect] を選択します。

認証コードのフロー

  1. 以下の詳細を入力して認証コードフローを有効にします。

    1. [付与タイプの選択] セクションの [コードのフロー] を選択します。

    2. プロバイダの名前。プロバイダ ID と同じでも、カスタム名でも構いません。カスタム名を入力する場合は、[プロバイダ ID] の横にある [編集] をクリックして ID を指定します(oidc. で始める必要があります)。

    3. プロバイダの [クライアント ID]。

    4. プロバイダの 発行元https://example.com のようになります。Identity Platform は、この URL を使用して、プロバイダの OAuth エンドポイントと公開鍵を指定する OIDC ディスカバリ ドキュメント(通常は /.well-known/openid-configuration にあります)を検索します。

    5. プロバイダの [クライアント シークレット]。

  2. [承認済みドメイン] のリストにアプリを追加します。たとえば、アプリのログイン URL が https://example.com/login の場合、example.com を追加します。

  3. OIDC プロバイダのリダイレクト URL として、Identity Platform のコールバック URL を構成します。URL は https://[PROJECT-ID].firebaseapp.com/__/auth/handler のような形式になります。

  4. [保存] をクリックします。

暗黙的フロー

  1. 暗黙的フローを有効にするには、次の詳細を入力します。

    1. [付与タイプを選択] セクションで [暗黙的フロー] を選択します。

    2. プロバイダの名前。プロバイダ ID と同じでも、カスタム名でも構いません。カスタム名を入力する場合は、[プロバイダ ID] の横にある [編集] をクリックして ID を指定します(oidc. で始める必要があります)。

    3. プロバイダの [クライアント ID]。

    4. プロバイダの 発行元https://example.com. Identity Platform でこの URL を使用して、プロバイダの OAuth エンドポイントと公開 URL を指定する OIDC ディスカバリ ドキュメント(通常は /.well-known/openid-configuration にあります)を探します。

  2. [承認済みドメイン] のリストにアプリを追加します。たとえば、アプリのログイン URL が https://example.com/login の場合、example.com を追加します。

  3. OIDC プロバイダのリダイレクト URL として、Identity Platform のコールバック URL を構成します。URL は https://[PROJECT-ID].firebaseapp.com/__/auth/handler のような形式になります。

  4. [保存] をクリックします。

ユーザーのログイン

OIDC でログインするには、次の 2 つの方法があります。

  • OAuth フローの使用。この方法では OAuth handshake が実行されます。GCIP サーバーは、プロバイダの構成ステップでの認証コードフロー/暗黙的フローの選択に基づき、ID プロバイダと通信する目的のフローを選択します。

  • OIDC プロバイダの ID トークンを使用する。この方法は、OIDC トークンがすでに利用可能であることを前提としています。

OAuth によるユーザーのログイン

OAuth を使用してログインするには、次のようにします。

  1. 前のセクションで構成したプロバイダ ID で OAuthProvider インスタンスを作成します。プロバイダ ID の先頭は oidc. にする必要があります。

    Web バージョン 9

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider("oidc.myProvider");

    Web バージョン 8

    const provider = new firebase.auth.OAuthProvider('oidc.myProvider');
  2. ログインフローを開始します。ポップアップまたはリダイレクトのいずれかを使用できます。

    Web バージョン 9

    import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        // User is signed in.
        const credential = OAuthProvider.credentialFromResult(result);
        // This gives you an access token for the OIDC provider. You can use it to directly interact with that provider
      }).catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
        // The email of the user's account used.
        const email = error.customData.email;
        // The AuthCredential type that was used.
        const credential = OAuthProvider.credentialFromError(error);
        // Handle / display error.
        // ...
      });

    Web バージョン 8

    firebase.auth().signInWithPopup(provider)
      .then((result) => {
        // User is signed in.
        // result.credential is a firebase.auth().OAuthCredential object.
        // result.credential.providerId is equal to 'oidc.myProvider'.
        // result.credential.idToken is the OIDC provider's ID token.
      })
      .catch((error) => {
        // Handle error.
      });

    リダイレクト

    ログインページにリダイレクトするには、signInWithRedirect() を呼び出します。

    Web バージョン 9

    import { getAuth, signInWithRedirect } from "firebase/auth";
    
    const auth = getAuth();
    signInWithRedirect(auth, provider);

    Web バージョン 8

    firebase.auth().signInWithRedirect(provider).catch((error) => {
      // Handle error.
    });

    次に、getRedirectResult() を呼び出して、ユーザーがアプリに戻ったときに結果を取得します。

    Web バージョン 9

    import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    getRedirectResult(auth)
      .then((result) => {
        // User is signed in.
        const credential = OAuthProvider.credentialFromResult(result);
        // This gives you an access token for the OIDC provider. You can use it to directly interact with that provider
      })
      .catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
        // The email of the user's account used.
        const email = error.customData.email;
        // The AuthCredential type that was used.
        const credential = OAuthProvider.credentialFromError(error);
        // Handle / display error.
        // ...
      });

    Web バージョン 8

    // On return.
    firebase.auth().getRedirectResult()
      .then((result) => {
        // User is signed in.
        // result.credential is a firebase.auth().OAuthCredential object.
        // result.credential.providerId is equal to 'oidc.myProvider'.
        // result.credential.idToken is the OIDC provider's ID token.
      })
      .catch((error) => {
        // Handle / display error.
        // ...
      });

どちらのフローでも、result.credential.idToken フィールドを使用して OIDC ID トークンを取得できます。

ユーザーの直接ログイン

OIDC ID トークンを使用してユーザーを直接ログインさせるには、次のようにします。

  1. 前のセクションで構成したプロバイダ ID で OAuthProvider インスタンスを初期化します。プロバイダ ID の先頭は oidc. にする必要があります。次に、OAuthCredential を作成し、signInWithCredential() を呼び出してユーザーをログインさせます。

    Web バージョン 9

    import { getAuth, OAuthProvider, signInWithCredential } from "firebase/auth";
    
    const auth = getAuth();
    const credential = provider.credential({
      idToken: oidcIdToken,
    });
    signInWithCredential(auth, credential)
      .then((result) => {
        // User is signed in.
        const newCredential = OAuthProvider.credentialFromResult(result);
        // This gives you a new access token for the OIDC provider. You can use it to directly interact with that provider.
      })
      .catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
        // The email of the user's account used.
        const email = error.customData.email;
        // The AuthCredential type that was used.
        const credential = OAuthProvider.credentialFromError(error);
        // Handle / display error.
        // ...
      });

    Web バージョン 8

    const credential = provider.credential(oidcIdToken, null);
    
    firebase.auth().signInWithCredential(credential)
      .then((result) => {
        // User is signed in.
        // User now has a odic.myProvider UserInfo in providerData.
      })
      .catch((error) => {
        // Handle / display error.
        // ...
      });

ユーザー アカウントのリンク

ユーザーが別の方法(メールアドレスとパスワードなど)を使用してすでにアプリにログインしている場合は、linkWithPopup() または linkWithRedirect() を使用して、既存のアカウントを OIDC プロバイダにリンクできます。たとえば、Google アカウントにリンクできます。

Web バージョン 9

import { getAuth, linkWithPopup, GoogleAuthProvider } from "firebase/auth";
const provider = new GoogleAuthProvider();

const auth = getAuth();
linkWithPopup(auth.currentUser, provider).then((result) => {
  // Accounts successfully linked.
  const credential = GoogleAuthProvider.credentialFromResult(result);
  const user = result.user;
  // ...
}).catch((error) => {
  // Handle Errors here.
  // ...
});

Web バージョン 8

auth.currentUser.linkWithPopup(provider).then((result) => {
  // Accounts successfully linked.
  var credential = result.credential;
  var user = result.user;
  // ...
}).catch((error) => {
  // Handle Errors here.
  // ...
});

次のステップ