Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

授權發送請求

從您的應用服務器或受信任環境發送到 FCM 的請求必須經過授權。請注意舊 HTTP 和 HTTP v1 API 授權之間的這些重要區別:

  • FCM HTTP v1 API 使用短期 OAuth 2.0 訪問令牌授權請求。要創建此令牌,您可以使用 Google 應用程序默認憑據(在 Google 服務器環境中)和/或從為服務帳戶生成的 JSON 私鑰文件中手動獲取所需的憑據。如果您使用 Firebase Admin SDK 發送消息,該庫會為您處理令牌。
  • 舊協議只能使用從 Firebase 控制台獲取的長期 API 密鑰。

授權 HTTP v1 發送請求

根據您的服務器環境的詳細信息,使用這些策略的組合來授權對 Firebase 服務的服務器請求:

  • Google 應用默認憑據 (ADC)
  • 服務帳號 JSON 文件
  • 從服務帳戶派生的短期 OAuth 2.0 訪問令牌

如果您的應用程序在計算引擎,谷歌Kubernetes引擎,應用程序引擎,或雲功能(包括火力地堡雲功能),使用應用程序的默認憑證(ADC)上運行。 ADC使用您現有的默認服務帳戶來獲得憑據來授權請求,以及ADC能夠通過環境變量靈活的本地測試GOOGLE_APPLICATION_CREDENTIALS 。為了最大限度地自動化授權流程,請將 ADC 與 Admin SDK 服務器庫一起使用。

如果您的應用程序在非谷歌服務器環境中運行,你需要從你的火力地堡項目下載服務帳戶JSON文件。只要你能夠訪問包含私有密鑰文件的文件系統,可以使用環境變量GOOGLE_APPLICATION_CREDENTIALS授權使用這些手動獲得證書的請求。如果您缺乏此類文件訪問權限,則必須在代碼中引用服務帳戶文件 - 由於存在暴露憑據的風險,因此應格外小心。

使用 ADC 提供憑據

Google 應用默認憑據 (ADC) 按以下順序檢查您的憑據:

  1. ADC檢查是否在環境變量GOOGLE_APPLICATION_CREDENTIALS設置。如果設置了該變量,ADC 將使用該變量指向的服務帳戶文件。

  2. 如果未設置環境變量,ADC 將使用 Compute Engine、Google Kubernetes Engine、App Engine 和 Cloud Functions 為在這些服務上運行的應用程序提供的默認服務帳戶。

  3. 如果 ADC 無法使用上述任一憑據,則係統會引發錯誤。

以下 Admin SDK 代碼示例說明了此策略。該示例沒有明確指定應用程序憑據。但是,只要設置了環境變量,或者只要應用程序在 Compute Engine、Google Kubernetes Engine、App Engine 或 Cloud Functions 上運行,ADC 就能夠隱式查找憑據。

節點.js

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});

爪哇

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);

Python

default_app = firebase_admin.initialize_app()

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});

手動提供憑據

火力地堡項目支持谷歌服務帳戶,您可以用它來從你的應用服務器或受信任的環境中調用火力地堡服務器API。如果您在本地開發代碼或在本地部署應用程序,則可以使用通過此服務帳戶獲得的憑據來授權服務器請求。

要對服務帳號進行身份驗證並授權其訪問 Firebase 服務,您必須生成一個 JSON 格式的私鑰文件。

要為您的服務帳戶生成私鑰文件:

  1. 在火力地堡控制台,打開設置>服務帳戶

  2. 點擊生成新的私鑰,然後點擊確認生成密鑰

  3. 安全地存儲包含密鑰的 JSON 文件。

通過服務帳戶進行授權時,您有兩種選擇來為您的應用程序提供憑據。您可以設置GOOGLE_APPLICATION_CREDENTIALS環境變量,也可以明確地傳遞的路徑,在代碼中的服務帳戶的關鍵。第一個選項更安全,強烈推薦。

要設置環境變量:

設置環境變量GOOGLE_APPLICATION_CREDENTIALS包含您的服務帳戶的關鍵JSON文件的文件路徑。此變量僅適用於您當前的 shell 會話,因此如果您打開一個新會話,請再次設置該變量。

Linux 或 macOS

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

視窗

使用 PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

完成上述步驟後,應用程序默認憑據 (ADC) 能夠隱式確定您的憑據,從而允許您在非 Google 環境中測試或運行時使用服務帳戶憑據。

使用憑據鑄造訪問令牌

除非您使用的是管理員SDK ,它處理權限自動,你需要薄荷令牌的訪問,並添加它來發送請求。

與使用您的火力地堡憑據一起谷歌驗證庫您的首選語言來獲取令牌短命的OAuth 2.0存取:

節點.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    const key = require('../placeholders/service-account.json');
    const jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

在此示例中,Google API 客戶端庫使用 JSON Web 令牌或 JWT 對請求進行身份驗證。欲了解更多信息,請參閱JSON網絡令牌

Python

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = ServiceAccountCredentials.from_json_keyfile_name(
      'service-account.json', SCOPES)
  access_token_info = credentials.get_access_token()
  return access_token_info.access_token

爪哇

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refreshAccessToken();
  return googleCredentials.getAccessToken().getTokenValue();
}

訪問令牌過期後,會自動調用令牌刷新方法以檢索更新的訪問令牌。

授權訪問FCM,請求範圍https://www.googleapis.com/auth/firebase.messaging

要將訪問令牌添加到 HTTP 請求標頭:

添加令牌作為的值Authorization在格式頭Authorization: Bearer <access_token>

節點.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Python

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

爪哇

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

授權舊協議發送請求

與HTTP遺留協議中,每個請求必須包含從服務器密鑰雲消息的火力地堡控制台設置窗格的選項卡。對於 XMPP,您必須使用相同的服務器密鑰來建立連接。

遷移舊服務器密鑰

從 2020 年 3 月開始,FCM 停止創建舊服務器密鑰。現有的傳統服務器密鑰將繼續工作,但我們建議您改為使用鍵標記服務器密鑰的更新版本中火力地堡控制台

如果要刪除現有的傳統服務器密鑰,您可以在這樣做谷歌雲端控制台

授權 HTTP 請求

消息請求由兩部分組成:HTTP 標頭和 HTTP 正文。 HTTP 標頭必須包含以下標頭:

  • Authorization :鍵= YOUR_SERVER_KEY
    確保這是服務器密鑰,其值是可用的雲計算消息的火力地堡控制台設置面板的選項卡。 FCM 拒絕 Android、iOS 和瀏覽器密鑰。
  • Content-Typeapplication/json的JSON; application/x-www-form-urlencoded;charset=UTF-8為純文本。
    如果Content-Type被省略,格式被認為是純文本。

例如:

Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    ...
  },
}

構建發送請求創建發送請求的全部細節。在傳統的HTTP協議參考提供了所有的消息可以包含的參數列表。

檢查服務器密鑰的有效性

如果您在發送消息時收到身份驗證錯誤,請檢查您的服務器密鑰的有效性。例如,在 Linux 上,運行以下命令:

api_key=YOUR_SERVER_KEY

curl --header "Authorization: key=$api_key" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"registration_ids\":[\"ABC\"]}"

如果您收到 401 HTTP 狀態代碼,則您的服務器密鑰無效。

授權 XMPP 連接

使用 XMPP,您可以保持與 FCM 服務器的持久、異步、雙向連接。該連接可用於在您的服務器和您用戶的 FCM 連接設備之間發送和接收消息。

您可以使用大多數 XMPP 庫來管理與 FCM 的長期連接。 XMPP在端點運行fcm-xmpp.googleapis.com:5235 。當測試與非生產用戶的功能,則應該連接到預生產服務器在fcm-xmpp.googleapis.com:5236 (注意不同的端口)。

對預生產(運行最新 FCM 構建的較小環境)進行定期測試有利於將真實用戶與測試代碼隔離開來。測試設備和測試代碼連接到fcm-xmpp.googleapis.com:5236應使用不同的FCM發送方ID,以避免發送測試消息,以生產用戶或以上測試連接從生產流量發送上行消息的任何風險。

連接有兩個重要的要求:

  • 您必須啟動傳輸層安全 (TLS) 連接。需要注意的是FCM目前不支持STARTTLS擴展
  • FCM需要使用SASL PLAIN認證機制<your_FCM_Sender_Id>@fcm.googleapis.com (FCM發送者ID ),並作為口令的服務器密鑰。這些值在可用的雲計算消息的火力地堡控制台設置面板的選項卡。

如果在任何時候連接失敗,您應該立即重新連接。在身份驗證後發生斷開連接後,無需退出。對於每一個發送者ID ,FCM允許並聯2500連接。

以下代碼段說明瞭如何對 FCM 的 XMPP 連接執行身份驗證和授權。

XMPP 服務器

XMPP 服務器請求連接到 FCM

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

FCM打開連接並請求一個auth機制,包括PLAIN方法。

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-OAUTH2</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

XMPP 服務器

XMPP服務器必須響應使用PLAIN身份驗證方法,提供從服務器密鑰雲端通訊的火力地堡控制台設置面板的選項卡。

<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>

FCM

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

XMPP 服務器

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

XMPP 服務器

<iq type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"></bind>
</iq>

FCM

<iq type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>SENDER_ID@fcm.googleapis.com/RESOURCE</jid>
  </bind>
</iq>

注意:FCM 在路由消息時不使用綁定資源。

構建發送請求創建發送請求的全部細節。該遺產XMPP協議參考提供了所有的消息可以包含的參數列表。