REST リクエストの認証

Firebase SDK は、ユーザーに代わり Firebase Realtime Database とのすべての認証と通信を処理します。ただし、クライアント SDK がない環境の場合や、永続的なデータベース接続のオーバーヘッドを避けたい場合は、Realtime Database REST API を使用してデータの読み取りと書き込みを行うことができます。

次のいずれかの方法でユーザーを認証します。

  1. Google OAuth2 アクセス トークン - 通常、Realtime Database に対する読み取り / 書き込み権限は、Realtime Database ルールによって管理されます。ただし、サーバーからデータにアクセスし、サービス アカウントから生成された Google OAuth2 アクセス トークンを使用して、データに対する完全な読み取りおよび書き込みのアクセス権をサーバーに付与できます。

  2. Firebase ID トークン: クライアント SDK の Realtime Database ルールによりアクセスを制限するなど、個々のユーザーとして認証されたリクエストを送信することもできます。REST API は、クライアント SDK で使用される Firebase ID トークンと同一のトークンを受け入れます。

Google OAuth2 アクセス トークン

Realtime Database ルールに従って一般に公開された読み取りまたは書き込み可能なデータは、認証を行わずに REST API 経由でも読み取りおよび書き込みが可能です。ただし、サーバーで Realtime Database ルールをバイパスする場合は、読み取りおよび書き込みのリクエストを認証する必要があります。Google OAuth2 による認証では、次の手順を実行する必要があります。

  1. アクセス トークンを生成します。
  2. そのアクセス トークンを使用して認証します。

アクセス トークンを生成する

Realtime Database REST API は、標準の Google OAuth2 アクセス トークンを受け入れます。アクセス トークンは、Realtime Database に対する適切な権限を持つサービス アカウントを使用して生成できます。新しいサービス アカウントの鍵ファイルをまだ生成していない場合は、Firebase コンソールで [サービス アカウント] セクションの下部にある [新しい秘密鍵を生成] ボタンをクリックすると、簡単に生成できます。

サービス アカウントの鍵ファイルを取得したら、Google API クライアント ライブラリの 1 つを使用して、次の必要なスコープで Google OAuth2 アクセス トークンを生成できます。

  • https://www.googleapis.com/auth/userinfo.email
  • https://www.googleapis.com/auth/firebase.database

次に、Realtime Database REST API での認証に使用する Google OAuth2 アクセス トークンをさまざまな言語で作成する方法について、いくつか実装例を示します。

Node.js

Node.js 用 Google API クライアント ライブラリを使用した場合:

var {google} = require("googleapis");

// Load the service account key JSON file.
var serviceAccount = require("path/to/serviceAccountKey.json");

// Define the required scopes.
var scopes = [
  "https://www.googleapis.com/auth/userinfo.email",
  "https://www.googleapis.com/auth/firebase.database"
];

// Authenticate a JWT client with the service account.
var jwtClient = new google.auth.JWT(
  serviceAccount.client_email,
  null,
  serviceAccount.private_key,
  scopes
);

// Use the JWT client to generate an access token.
jwtClient.authorize(function(error, tokens) {
  if (error) {
    console.log("Error making request to generate access token:", error);
  } else if (tokens.access_token === null) {
    console.log("Provided service account does not have permission to generate access tokens");
  } else {
    var accessToken = tokens.access_token;

    // See the "Using the access token" section below for information
    // on how to use the access token to send authenticated requests to
    // the Realtime Database REST API.
  }
});

Java

Java 用 Google API クライアント ライブラリを使用した場合:

// Load the service account key JSON file
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");

// Authenticate a Google credential with the service account
GoogleCredential googleCred = GoogleCredential.fromStream(serviceAccount);

// Add the required scopes to the Google credential
GoogleCredential scoped = googleCred.createScoped(
    Arrays.asList(
      "https://www.googleapis.com/auth/firebase.database",
      "https://www.googleapis.com/auth/userinfo.email"
    )
);

// Use the Google credential to generate an access token
scoped.refreshToken();
String token = scoped.getAccessToken();

// See the "Using the access token" section below for information
// on how to use the access token to send authenticated requests to the
// Realtime Database REST API.

Python

google-auth ライブラリを使用した場合:

from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession

# Define the required scopes
scopes = [
  "https://www.googleapis.com/auth/userinfo.email",
  "https://www.googleapis.com/auth/firebase.database"
]

# Authenticate a credential with the service account
credentials = service_account.Credentials.from_service_account_file(
    "path/to/serviceAccountKey.json", scopes=scopes)

# Use the credentials object to authenticate a Requests session.
authed_session = AuthorizedSession(credentials)
response = authed_session.get(
    "https://<DATABASE_NAME>.firebaseio.com/users/ada/name.json")

# Or, use the token directly, as described in the "Authenticate with an
# access token" section below. (not recommended)
request = google.auth.transport.requests.Request()
credentials.refresh(request)
access_token = credentials.token

アクセス トークンによる認証

認証されたリクエストを Realtime Database REST API に送信するには、先ほど生成したGoogle OAuth2 アクセス トークンを Authorization: Bearer <ACCESS_TOKEN> ヘッダーまたは access_token=<ACCESS_TOKEN> クエリ文字列パラメータとして渡します。次に、Ada の名前を読み取る curl リクエストの例を示します。

curl "https://<DATABASE_NAME>.firebaseio.com/users/ada/name.json?access_token=<ACCESS_TOKEN>"

<DATABASE_NAME>Realtime Database の名前で置き換え、<ACCESS_TOKEN> は Google OAuth2 アクセス トークンで置き換えてください。

成功したリクエストは 200 OK HTTP ステータス コードで示されます。レスポンスには取得されるデータが含まれます。

{"first":"Ada","last":"Lovelace"}

Firebase ID トークン

Firebase Authentication を使用することによるユーザーのログインまたはデバイスでのログインが成功すると、Firebase で対応する ID トークンが作成され、この ID トークンでユーザーまたはデバイスを一意に特定し、Realtime DatabaseCloud Storage などのリソースへのアクセス権を付与します。その ID トークンを再利用して、Realtime Database REST API を認証し、そのユーザーに代わってリクエストを送信できます。

ID トークンを生成する

クライアントから Firebase ID トークンを取得するには、クライアントで ID トークンを取得するに記載の手順に従います。

ID トークンは短期間で有効期限が切れるので、取得後はできるだけ早く使用する必要があります。

ID トークンによる認証

認証されたリクエストを Realtime Database REST API に送信するには、先ほど生成した ID トークンを auth=<ID_TOKEN> クエリ文字列パラメータとして渡します。次に、Ada の名前を読み取る curl リクエストの例を示します。

curl "https://<DATABASE_NAME>.firebaseio.com/users/ada/name.json?auth=<ID_TOKEN>"

<DATABASE_NAME>Realtime Database の名前で置き換え、<ID_TOKEN> は Firebase ID トークンで置き換えてください。

成功したリクエストは 200 OK HTTP ステータス コードで示されます。レスポンスには取得されるデータが含まれます。

{"first":"Ada","last":"Lovelace"}

従来のトークン

従来の Firebase 認証トークンを使用している場合は、REST 認証を上記のいずれかの認証方法に更新することをおすすめします。

Realtime Database REST API は、シークレットを含む、以前の認証トークンを使用した認証を引き続きサポートしています。Realtime Database シークレットは、Firebase コンソールの [サービス アカウント] セクションに表示されます。

シークレットは有効期間の長い認証情報です。シークレットへのアクセス権を持つユーザー(オーナーなど)をプロジェクトから削除する場合は、新しいシークレットを生成して既存のシークレットを取り消すことをおすすめします。