Sendeanforderungen autorisieren

Von Ihrem App-Server oder Ihrer vertrauenswürdigen Umgebung an FCM gesendete Anforderungen müssen autorisiert werden. Beachten Sie diese wichtigen Unterschiede zwischen der veralteten Legacy-HTTP-API und der HTTP v1-API-Autorisierung:

  • Die FCM HTTP v1 API autorisiert Anfragen mit einem kurzlebigen OAuth 2.0-Zugriffstoken. Um dieses Token zu prägen, können Sie die Standardanmeldeinformationen für Google-Anwendungen verwenden (in Google-Serverumgebungen) und/oder die erforderlichen Anmeldeinformationen manuell aus einer privaten JSON-Schlüsseldatei abrufen, die für ein Dienstkonto generiert wurde. Wenn Sie das Firebase Admin SDK zum Senden von Nachrichten verwenden, verwaltet die Bibliothek das Token für Sie.
  • Die veralteten Legacy-Protokolle können nur langlebige API-Schlüssel verwenden, die von der Firebase-Konsole abgerufen werden.

Autorisieren Sie HTTP v1-Sendeanforderungen

Abhängig von den Details Ihrer Serverumgebung verwenden Sie eine Kombination dieser Strategien, um Serveranfragen an Firebase-Dienste zu autorisieren:

  • Standardanmeldeinformationen für Google-Anwendungen (ADC)
  • Eine JSON-Datei für ein Dienstkonto
  • Ein kurzlebiges OAuth 2.0-Zugriffstoken, das von einem Dienstkonto abgeleitet ist

Wenn Ihre Anwendung auf Compute Engine, Google Kubernetes Engine, App Engine oder Cloud Functions (einschließlich Cloud Functions für Firebase) ausgeführt wird , verwenden Sie Application Default Credentials (ADC). ADC verwendet Ihr vorhandenes Standarddienstkonto, um Anmeldeinformationen zum Autorisieren von Anforderungen abzurufen, und ADC ermöglicht flexible lokale Tests über die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS . Für die vollständigste Automatisierung des Autorisierungsablaufs verwenden Sie ADC zusammen mit Admin SDK-Serverbibliotheken.

Wenn Ihre Anwendung in einer Nicht-Google-Serverumgebung ausgeführt wird , müssen Sie eine JSON-Datei für ein Dienstkonto aus Ihrem Firebase-Projekt herunterladen. Solange Sie Zugriff auf ein Dateisystem haben, das die private Schlüsseldatei enthält, können Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS verwenden, um Anfragen mit diesen manuell erhaltenen Anmeldeinformationen zu autorisieren. Wenn Sie keinen solchen Dateizugriff haben, müssen Sie in Ihrem Code auf die Dienstkontodatei verweisen. Dies sollte mit äußerster Sorgfalt erfolgen, da das Risiko besteht, dass Ihre Anmeldeinformationen preisgegeben werden.

Geben Sie Anmeldeinformationen mithilfe von ADC an

Google Application Default Credentials (ADC) prüft Ihre Anmeldeinformationen in der folgenden Reihenfolge:

  1. ADC prüft, ob die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS gesetzt ist. Wenn die Variable festgelegt ist, verwendet ADC die Dienstkontodatei, auf die die Variable verweist.

  2. Wenn die Umgebungsvariable nicht festgelegt ist, verwendet ADC das Standarddienstkonto, das Compute Engine, Google Kubernetes Engine, App Engine und Cloud Functions für Anwendungen bereitstellen, die auf diesen Diensten ausgeführt werden.

  3. Wenn ADC keine der oben genannten Anmeldeinformationen verwenden kann, gibt das System einen Fehler aus.

Das folgende Admin SDK-Codebeispiel veranschaulicht diese Strategie. Im Beispiel werden die Anmeldeinformationen der Anwendung nicht explizit angegeben. ADC ist jedoch in der Lage, die Anmeldeinformationen implizit zu finden, solange die Umgebungsvariable festgelegt ist oder die Anwendung auf Compute Engine, Google Kubernetes Engine, App Engine oder Cloud Functions ausgeführt wird.

Node.js

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

Java

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

FirebaseApp.initializeApp(options);

Python

default_app = firebase_admin.initialize_app()

Gehen

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(),
});

Geben Sie die Anmeldeinformationen manuell ein

Firebase-Projekte unterstützen Google- Dienstkonten , mit denen Sie Firebase-Server-APIs von Ihrem App-Server oder Ihrer vertrauenswürdigen Umgebung aus aufrufen können. Wenn Sie Code lokal entwickeln oder Ihre Anwendung lokal bereitstellen, können Sie die über dieses Dienstkonto erhaltenen Anmeldeinformationen verwenden, um Serveranfragen zu autorisieren.

Um ein Dienstkonto zu authentifizieren und es für den Zugriff auf Firebase-Dienste zu autorisieren, müssen Sie eine private Schlüsseldatei im JSON-Format generieren.

So generieren Sie eine private Schlüsseldatei für Ihr Dienstkonto:

  1. Öffnen Sie in der Firebase-Konsole Einstellungen > Dienstkonten .

  2. Klicken Sie auf „Neuen privaten Schlüssel generieren“ und bestätigen Sie dann, indem Sie auf „Schlüssel generieren“ klicken.

  3. Speichern Sie die JSON-Datei, die den Schlüssel enthält, sicher.

Bei der Autorisierung über ein Dienstkonto haben Sie zwei Möglichkeiten, die Anmeldeinformationen für Ihre Anwendung bereitzustellen. Sie können entweder die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS festlegen oder den Pfad zum Dienstkontoschlüssel explizit im Code übergeben. Die erste Option ist sicherer und wird dringend empfohlen.

So legen Sie die Umgebungsvariable fest:

Legen Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS auf den Dateipfad der JSON-Datei fest, die Ihren Dienstkontoschlüssel enthält. Diese Variable gilt nur für Ihre aktuelle Shell-Sitzung. Wenn Sie also eine neue Sitzung öffnen, legen Sie die Variable erneut fest.

Linux oder macOS

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

Windows

Mit PowerShell:

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

Nachdem Sie die oben genannten Schritte ausgeführt haben, kann Application Default Credentials (ADC) Ihre Anmeldeinformationen implizit ermitteln, sodass Sie beim Testen oder Ausführen in Nicht-Google-Umgebungen Dienstkonto-Anmeldeinformationen verwenden können.

Verwenden Sie Anmeldeinformationen, um Zugriffstoken zu erstellen

Sofern Sie nicht das Admin SDK verwenden, das die Autorisierung automatisch übernimmt, müssen Sie das Zugriffstoken prägen und zum Senden von Anfragen hinzufügen.

Verwenden Sie Ihre Firebase-Anmeldeinformationen zusammen mit der Google Auth Library für Ihre bevorzugte Sprache, um ein kurzlebiges OAuth 2.0-Zugriffstoken abzurufen:

node.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);
    });
  });
}

In diesem Beispiel authentifiziert die Google API-Clientbibliothek die Anfrage mit einem JSON-Web-Token oder JWT. Weitere Informationen finden Sie unter JSON-Web-Tokens .

Python

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

  :return: Access token.
  """
  credentials = service_account.Credentials.from_service_account_file(
    'service-account.json', scopes=SCOPES)
  request = google.auth.transport.requests.Request()
  credentials.refresh(request)
  return credentials.token

Java

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

Nachdem Ihr Zugriffstoken abgelaufen ist, wird die Token-Aktualisierungsmethode automatisch aufgerufen, um ein aktualisiertes Zugriffstoken abzurufen.

Um den Zugriff auf FCM zu autorisieren, fordern Sie den Bereich https://www.googleapis.com/auth/firebase.messaging an.

So fügen Sie das Zugriffstoken einem HTTP-Anforderungsheader hinzu:

Fügen Sie das Token als Wert des Authorization Headers im Format Authorization: Bearer <access_token> hinzu:

node.js

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

Python

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

Java

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

Autorisieren Sie Sendeanforderungen für Legacy-Protokolle

Beim HTTP-Legacy-Protokoll muss jede Anfrage den Serverschlüssel aus der Registerkarte „Cloud Messaging“ des Bereichs „Einstellungen“ der Firebase-Konsole enthalten. Für XMPP müssen Sie denselben Serverschlüssel verwenden, um eine Verbindung herzustellen.

Ältere Serverschlüssel migrieren

Ab März 2020 hat FCM die Erstellung älterer Serverschlüssel eingestellt. Vorhandene ältere Serverschlüssel funktionieren weiterhin, wir empfehlen jedoch, stattdessen die neuere Version des Schlüssels mit der Bezeichnung „Serverschlüssel“ in der Firebase-Konsole zu verwenden.

Wenn Sie einen vorhandenen Legacy-Serverschlüssel löschen möchten, können Sie dies in der Google Cloud Console tun.

Autorisieren Sie HTTP-Anfragen

Eine Nachrichtenanforderung besteht aus zwei Teilen: dem HTTP-Header und dem HTTP-Body. Der HTTP-Header muss die folgenden Header enthalten:

  • Authorization : key=YOUR_SERVER_KEY
    Stellen Sie sicher, dass es sich hierbei um den Serverschlüssel handelt, dessen Wert auf der Registerkarte „Cloud Messaging“ im Bereich „ Einstellungen“ der Firebase-Konsole verfügbar ist. Android-, Apple-Plattform- und Browserschlüssel werden von FCM abgelehnt.
  • Content-Type : application/json für JSON; application/x-www-form-urlencoded;charset=UTF-8 für Klartext.
    Wenn Content-Type weggelassen wird, wird davon ausgegangen, dass es sich bei dem Format um Nur-Text handelt.

Zum Beispiel:

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

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

Ausführliche Informationen zum Erstellen von Sendeanforderungen finden Sie unter „Sendeanforderungen erstellen “. Die Referenz zum Legacy-HTTP-Protokoll enthält eine Liste aller Parameter, die Ihre Nachricht enthalten kann.

Überprüfung der Gültigkeit eines Serverschlüssels

Wenn Sie beim Senden von Nachrichten Authentifizierungsfehler erhalten, überprüfen Sie die Gültigkeit Ihres Serverschlüssels. Führen Sie unter Linux beispielsweise den folgenden Befehl aus:

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\"]}"

Wenn Sie den HTTP-Statuscode 401 erhalten, ist Ihr Serverschlüssel ungültig.

Autorisieren Sie eine XMPP-Verbindung

Mit XMPP können Sie eine dauerhafte, asynchrone, bidirektionale Verbindung zu FCM-Servern aufrechterhalten. Die Verbindung kann zum Senden und Empfangen von Nachrichten zwischen Ihrem Server und den mit FCM verbundenen Geräten Ihrer Benutzer verwendet werden.

Sie können die meisten XMPP-Bibliotheken verwenden, um eine langlebige Verbindung zu FCM zu verwalten. Der XMPP-Endpunkt wird unter fcm-xmpp.googleapis.com:5235 ausgeführt. Wenn Sie die Funktionalität mit Nicht-Produktionsbenutzern testen, sollten Sie stattdessen eine Verbindung zum Vorproduktionsserver unter fcm-xmpp.googleapis.com:5236 herstellen (beachten Sie den anderen Port).

Regelmäßige Tests in der Vorproduktion (einer kleineren Umgebung, in der die neuesten FCM-Builds ausgeführt werden) sind hilfreich, um echte Benutzer vom Testcode zu isolieren. Testgeräte und Testcode, die eine Verbindung zu fcm-xmpp.googleapis.com:5236 herstellen, sollten eine andere FCM-Absender-ID verwenden, um das Risiko des Sendens von Testnachrichten an Produktionsbenutzer oder des Sendens von Upstream-Nachrichten aus dem Produktionsverkehr über Testverbindungen zu vermeiden.

Die Verbindung hat zwei wichtige Anforderungen:

  • Sie müssen eine TLS-Verbindung (Transport Layer Security) initiieren. Beachten Sie, dass FCM derzeit die STARTTLS-Erweiterung nicht unterstützt.
  • FCM erfordert einen SASL PLAIN-Authentifizierungsmechanismus mit <your_FCM_Sender_Id>@fcm.googleapis.com (FCM- Absender-ID ) und dem Serverschlüssel als Passwort. Diese Werte sind auf der Registerkarte „Cloud Messaging“ im Bereich „Einstellungen“ der Firebase-Konsole verfügbar.

Sollte die Verbindung zu irgendeinem Zeitpunkt fehlschlagen, sollten Sie die Verbindung sofort wiederherstellen. Es besteht keine Notwendigkeit, nach einer Verbindungstrennung nach der Authentifizierung einen Rückzieher zu machen. Für jede Absender-ID erlaubt FCM 2500 Verbindungen parallel.

Die folgenden Ausschnitte veranschaulichen, wie die Authentifizierung und Autorisierung für eine XMPP-Verbindung zu FCM durchgeführt wird.

XMPP-Server

Der XMPP-Server fordert eine Verbindung zum FCM an

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

FCM

FCM öffnet die Verbindung und fordert einen Authentifizierungsmechanismus an, einschließlich der PLAIN Methode.

<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-Server

Der XMPP-Server muss mit der PLAIN Authentifizierungsmethode antworten und den Serverschlüssel von der Registerkarte „Cloud-Messaging“ im Bereich „Einstellungen“ der Firebase-Konsole bereitstellen.

<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-Server

<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-Server

<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>

Hinweis: FCM verwendet die gebundene Ressource beim Weiterleiten von Nachrichten nicht.

Ausführliche Informationen zum Erstellen von Sendeanforderungen finden Sie unter „Sendeanforderungen erstellen “. Die Referenz zum Legacy-XMPP-Protokoll enthält eine Liste aller Parameter, die Ihre Nachricht enthalten kann.