🐶

Identity Platform[GCP]の使い方(ついでにCloud runとの連携も)

2022/03/26に公開約2,600字

概要

公式以外に使用方法を日本語で説明したものが見当たらなかったので、記述します。

Identity Platformの説明

GCPのIDaaSサービスです。GCP関連だとFirebase Authrizationが基本だと思いますが、その裏で動いているのがIdentity Platformです。サービスの違いはとくにありませんが、違いは「マルチテナント機能」です。要するに、ユーザーグループ(≒テナント)に分けることができます。

基本的な使い方は、Firebase Authrizationと同じで、各言語のライブラリも同じものを使用します。Webブラウザ上で使用する際は「identitytoolkit」を使用し、基本的にFirebaseと同じ環境で大丈夫です。

サンプルスニペット

ここではJavaScriptで説明します。ここではjavascriptライブラリのversion9です。

初期化

configの内容は他にもあるので、適宜追加してください。以下は最低限の内容です。このあたりはFirebaseライブラリで必要な処理になるため、詳細は割愛します。

import { initializeApp } from "firebase/app";
const config = {
  apiKey: "~~",
  authDomain: ["localhost", "~~"],
};
initializeApp(config);

ログイン

ここでは関数ぽく書いていますが、関数の中身のみ参考にしてください(関数としてのテストはしていません)。

import {
  getAuth,
  EmailAuthProvider,
  signInWithCredential,
  setPersistence,
  browserLocalPersistence,
  getIdToken,
} from "firebase/auth";

export async function login(email, password){
  const auth = getAuth();
  auth.tenantId = "~~"; //マルチテナント機能を使用している場合は、テナント毎にこれを変更します。使用していない場合は必要ないです。
  // browserLocalPersistenceを指定していますが、これはsignOut関数を呼び出さない限り、ログイン状態を保持します。
  setPersistence(auth, browserLocalPersistence).then(async () => {
    // 今回はEmail+Passwordでのログイン
    const authCredential = EmailAuthProvider.credential(
      email,
      password
    );
    // 今回はEmail+Passwordでのログイン
    await signInWithCredential(auth, authCredential)
      .then(() => {
        // 正常処理
      })
      .catch(() => {
        // 異常処理
      });
  });
}

ついでにCloud runとの連携も

ここでは、Pythonでスニペットを示しています。
参考とは少し違いますが、マルチテナントを使用したときのことを以下にコメントで記載しました。以下からわかるように、firebase_adminを使用しているため、こちらの初期化関数の呼び出しが別途必要であることを留意してください。

from typing import Any, Callable
from firebase_admin import auth
from functools import wraps
from flask import request, Response

def jwt_authenticated(func: Callable[..., int]) -> Callable[..., int]:
    @wraps(func)
    def decorated_function(*args: Any, **kwargs: Any) -> Any:
        header = request.headers.get("Authorization", None)
        if header:
            token = header.split(" ")[1]
            try:
                decoded_token = auth.verify_id_token(token)
                # decoded_token["firebase"]["tenant"]から「tenantId」を取得できます。
            except Exception as e:
                return Response(status=403, response=f"Error with authentication: {e}")
        else:
            return Response(status=401)

        request.uid = decoded_token["uid"]
        return func(*args, **kwargs)

    return decorated_function

参考

Discussion

ログインするとコメントできます