对 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 客户端库生成具有以下所需范围的 Google OAuth2 访问令牌:

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

下面这些实现示例展示了如何使用各种不同的编程语言创建 Google OAuth2 访问令牌,以向 Realtime Database REST API 进行身份验证:

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 令牌以唯一标识用户或设备,并向其授予多个资源(例如 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 仍然支持通过旧版身份验证令牌(包括 Secret)进行身份验证。您可以在 Firebase 控制台的服务账号部分中找到您的 Realtime Database Secret。

Secret 是长期有效的凭据。我们建议您在从项目中移除拥有 Secret 访问权限的用户(例如所有者)时,生成新的 Secret 并撤消现有 Secret。