生成された Admin SDK を使用する

Firebase Data Connect Admin SDK を使用すると、Cloud Functions、カスタム バックエンド、独自の ワークステーションなどの 信頼できる環境からクエリとミューテーションを呼び出すことができます。クライアント アプリの SDK を生成するのと同様に、Data Connect サービスにデプロイするスキーマ、クエリ、ミューテーションを設計するのと並行して、カスタム Admin SDK を生成できます。Data Connect次に、この SDK のメソッドをバックエンド ロジックまたは管理スクリプトに統合します。

他の場所でも説明したように、Data Connect クエリ とミューテーションはリクエスト時にクライアントによって送信されないことに注意してください。 代わりに、デプロイされると、Data Connect オペレーションは Cloud Functions のようにサーバーに保存されます。つまり、クエリとミューテーションに変更をデプロイする場合は、Admin SDK を再生成し、それらに依存するサービスを再デプロイする必要があります。

始める前に

Admin SDK を生成する

Data Connect のスキーマ、クエリ、ミューテーションを作成したら、 対応する Admin SDK を生成できます。

  1. connector.yaml ファイルを開くか作成して、adminNodeSdk 定義を追加します。

    connectorId: default
    generate:
      adminNodeSdk:
        outputDir: ../../dataconnect-generated/admin-generated
        package: "@dataconnect/admin-generated"
        packageJsonDir: ../..
    

    connector.yaml ファイルは通常、クエリとミューテーションの定義を含む GraphQL(.gql)ファイルと同じディレクトリにあります。クライアント SDK をすでに生成している場合、このファイルはすでに作成されています。

  2. SDK を生成します。

    Data Connect VS Code 拡張機能がインストールされている場合、生成された SDK は常に最新の状態に保たれます。

    それ以外の場合は、Firebase CLI を使用します。

    firebase dataconnect:sdk:generate

    または、gql ファイルを更新したときに SDK を自動的に再生成するには:

    firebase dataconnect:sdk:generate --watch

Admin SDK からオペレーションを実行する

生成された Admin SDK には、gql 定義に対応するインターフェースと関数が含まれています。これを使用して、データベースに対してオペレーションを実行できます。たとえば、曲のデータベースの SDK をクエリ getSongs とともに生成したとします。

import { initializeApp } from "firebase-admin/app";
import { getSongs } from "@dataconnect/admin-generated";

const adminApp = initializeApp();

const songs = await getSongs(
  { limit: 4 },
  { impersonate: { unauthenticated: true } }
);

または、コネクタ構成を指定するには:

import { initializeApp } from "firebase-admin/app";
import { getDataConnect } from "firebase-admin/data-connect";
import {
  connectorConfig,
  getSongs,
} from "@dataconnect/admin-generated";

const adminApp = initializeApp();
const adminDc = getDataConnect(connectorConfig);

const songs = await getSongs(
  adminDc,
  { limit: 4 },
  { impersonate: { unauthenticated: true } }
);

認証されていないユーザーになりすます

Admin SDK は信頼できる環境から実行されることを想定しているため、データベースへのアクセスは無制限です。

Admin SDK で公開オペレーションを実行する場合は、完全な管理者権限でオペレーションを実行しないようにしてください(最小権限の原則に従います)。代わりに、なりすましユーザー(次のセクションを参照)またはなりすまし認証されていないユーザーとしてオペレーションを実行する必要があります。 認証されていないユーザーは、PUBLIC とマークされたオペレーションのみを実行できます。

上記の例では、getSongs クエリは認証されていないユーザーとして実行されます。

ユーザーになりすます

`impersonate` オプションで `Firebase Authentication` トークンの一部または すべてを渡すことで、特定のユーザーに代わってオペレーションを実行することもできます。少なくとも、サブクレームでユーザーのユーザー ID を指定する必要があります。(これは、GraphQL オペレーションで参照できる auth.uid サーバー値 と同じ値です)。Data Connect

ユーザーになりすます場合、提供したユーザーデータが GraphQL 定義で指定された認証チェックに合格した場合にのみ、オペレーションは成功します。

公開アクセス可能なエンドポイントから生成された SDK を呼び出す場合は、エンドポイントで認証を必須とし、認証トークンの整合性を検証してから、ユーザーになりすますことが重要です。

呼び出し可能な Cloud Functions を使用する場合、認証トークンは 自動的に検証され、次の例のように使用できます。

import { HttpsError, onCall } from "firebase-functions/https";

export const callableExample = onCall(async (req) => {
    const authClaims = req.auth?.token;
    if (!authClaims) {
        throw new HttpsError("unauthenticated", "Unauthorized");
    }

    const favoriteSongs = await getMyFavoriteSongs(
        undefined,
        { impersonate: { authClaims } }
    );

    // ...
});

それ以外の場合は、Admin SDK's verifyIdToken メソッドを使用して、認証トークンを検証してデコードします。たとえば、エンドポイントが プレーン HTTP 関数として実装され、Firebase Authentication トークンを 標準どおりに authorization ヘッダーを使用してエンドポイントに渡したとします。

import { getAuth } from "firebase-admin/auth";
import { onRequest } from "firebase-functions/https";

const auth = getAuth();

export const httpExample = onRequest(async (req, res) => {
    const token = req.header("authorization")?.replace(/^bearer\s+/i, "");
    if (!token) {
        res.sendStatus(401);
        return;
    }
    let authClaims;
    try {
        authClaims = await auth.verifyIdToken(token);
    } catch {
        res.sendStatus(401);
        return;
    }

    const favoriteSongs = await getMyFavoriteSongs(
        undefined,
        { impersonate: { authClaims } }
    );

    // ...
});

安全で公開アクセスできない環境からデータ移行などの真の管理タスクを実行する場合にのみ、検証可能なソースから生成されていないユーザー ID を指定する必要があります。

// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
  undefined,
  { impersonate: { authClaims } }
);

無制限のアクセス権で実行する

管理者レベルの権限を必要とするオペレーションを実行する場合は、呼び出しからなりすましパラメータを省略します。

await upsertSong(adminDc, {
  title: songTitle_one,
  instrumentsUsed: [Instrument.VOCAL],
});

この方法で呼び出されたオペレーションは、データベースに完全にアクセスできます。管理目的でのみ使用するクエリまたはミューテーションがある場合は、@auth(level: NO_ACCESS) ディレクティブで定義する必要があります。これにより、管理者レベルの呼び出し元のみがこれらのオペレーションを実行できるようになります。