了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

Autoriser les demandes d'envoi

Les requêtes envoyées à FCM depuis votre serveur d'applications ou votre environnement de confiance doivent être autorisées. Notez ces différences importantes entre l'ancienne autorisation d'API HTTP et HTTP v1 :

  • L'API FCM HTTP v1 autorise les requêtes avec un jeton d'accès OAuth 2.0 de courte durée. Pour créer ce jeton, vous pouvez utiliser les informations d'identification par défaut de l'application Google (dans les environnements de serveur Google) et/ou obtenir manuellement les informations d'identification requises à partir d'un fichier de clé privée JSON généré pour un compte de service. Si vous utilisez le SDK Firebase Admin pour envoyer des messages, la bibliothèque gère le jeton pour vous.
  • Les protocoles hérités ne peuvent utiliser que des clés API de longue durée obtenues à partir de la console Firebase.

Autoriser les requêtes d'envoi HTTP v1

Selon les détails de votre environnement de serveur, utilisez une combinaison de ces stratégies pour autoriser les requêtes du serveur aux services Firebase :

  • Identifiants par défaut de l'application Google (ADC)
  • Un fichier JSON de compte de service
  • Un jeton d'accès OAuth 2.0 de courte durée dérivé d'un compte de service

Si votre application s'exécute sur Compute Engine, Google Kubernetes Engine, App Engine ou Cloud Functions (y compris Cloud Functions pour Firebase), utilisez les identifiants par défaut de l'application (ADC). ADC utilise votre compte de service par défaut existant pour obtenir des informations d'identification pour autoriser les demandes, et ADC permet des tests locaux flexibles via la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS . Pour une automatisation complète du flux d'autorisation, utilisez ADC avec les bibliothèques de serveur Admin SDK.

Si votre application s'exécute sur un environnement de serveur autre que Google , vous devrez télécharger un fichier JSON de compte de service à partir de votre projet Firebase. Tant que vous avez accès à un système de fichiers contenant le fichier de clé privée, vous pouvez utiliser la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS pour autoriser les demandes avec ces informations d'identification obtenues manuellement. Si vous ne disposez pas d'un tel accès au fichier, vous devez référencer le fichier du compte de service dans votre code, ce qui doit être fait avec une extrême prudence en raison du risque d'exposer vos informations d'identification.

Fournir des informations d'identification à l'aide d'ADC

Google Application Default Credentials (ADC) vérifie vos identifiants dans l'ordre suivant :

  1. ADC vérifie si la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS est définie. Si la variable est définie, ADC utilise le fichier de compte de service vers lequel pointe la variable.

  2. Si la variable d'environnement n'est pas définie, ADC utilise le compte de service par défaut fourni par Compute Engine, Google Kubernetes Engine, App Engine et Cloud Functions pour les applications qui s'exécutent sur ces services.

  3. Si ADC ne peut pas utiliser l'une des informations d'identification ci-dessus, le système génère une erreur.

L'exemple de code du SDK d'administration suivant illustre cette stratégie. L'exemple ne spécifie pas explicitement les informations d'identification de l'application. Cependant, ADC est capable de trouver implicitement les identifiants tant que la variable d'environnement est définie ou tant que l'application s'exécute sur Compute Engine, Google Kubernetes Engine, App Engine ou Cloud Functions.

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

Aller

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

Fournir les informations d'identification manuellement

Les projets Firebase prennent en charge les comptes de service Google , que vous pouvez utiliser pour appeler les API du serveur Firebase à partir de votre serveur d'applications ou de votre environnement de confiance. Si vous développez du code localement ou déployez votre application sur site, vous pouvez utiliser les informations d'identification obtenues via ce compte de service pour autoriser les requêtes du serveur.

Pour authentifier un compte de service et l'autoriser à accéder aux services Firebase, vous devez générer un fichier de clé privée au format JSON.

Pour générer un fichier de clé privée pour votre compte de service :

  1. Dans la console Firebase, ouvrez Paramètres > Comptes de service .

  2. Cliquez sur Générer une nouvelle clé privée , puis confirmez en cliquant sur Générer la clé .

  3. Stockez en toute sécurité le fichier JSON contenant la clé.

Lors de l'autorisation via un compte de service, vous avez deux choix pour fournir les informations d'identification à votre application. Vous pouvez soit définir la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS , soit transmettre explicitement le chemin d'accès à la clé du compte de service dans le code. La première option est plus sécurisée et est fortement recommandée.

Pour définir la variable d'environnement :

Définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS sur le chemin d'accès au fichier JSON contenant la clé de votre compte de service. Cette variable ne s'applique qu'à votre session shell actuelle, donc si vous ouvrez une nouvelle session, définissez à nouveau la variable.

Linux ou macOS

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

les fenêtres

Avec PowerShell :

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

Une fois que vous avez terminé les étapes ci-dessus, les informations d'identification par défaut de l'application (ADC) peuvent déterminer implicitement vos informations d'identification, ce qui vous permet d'utiliser les informations d'identification du compte de service lors des tests ou de l'exécution dans des environnements autres que Google.

Utiliser les informations d'identification pour créer des jetons d'accès

À moins que vous n'utilisiez le SDK d'administration , qui gère l'autorisation automatiquement, vous devrez créer le jeton d'accès et l'ajouter pour envoyer des demandes.

Utilisez vos identifiants Firebase avec la bibliothèque Google Auth pour votre langue préférée afin de récupérer un jeton d'accès OAuth 2.0 de courte durée :

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

Dans cet exemple, la bibliothèque cliente de l'API Google authentifie la requête avec un jeton Web JSON ou JWT. Pour plus d'informations, consultez Jetons Web JSON .

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.refreshAccessToken();
  return googleCredentials.getAccessToken().getTokenValue();
}

Après l'expiration de votre jeton d'accès, la méthode d'actualisation du jeton est appelée automatiquement pour récupérer un jeton d'accès mis à jour.

Pour autoriser l'accès à FCM, demandez la portée https://www.googleapis.com/auth/firebase.messaging .

Pour ajouter le jeton d'accès à un en-tête de requête HTTP :

Ajoutez le jeton comme valeur de l'en-tête Authorization au format Authorization: Bearer <access_token> :

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 " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Autoriser les demandes d'envoi de protocole hérité

Avec l'ancien protocole HTTP, chaque requête doit contenir la clé de serveur de l'onglet Cloud Messaging du volet Paramètres de la console Firebase. Pour XMPP, vous devez utiliser la même clé de serveur pour établir une connexion.

Migrer les clés de serveur héritées

Depuis mars 2020, FCM a cessé de créer des clés de serveur héritées. Les clés de serveur héritées existantes continueront de fonctionner, mais nous vous recommandons d'utiliser à la place la version la plus récente de la clé intitulée Clé de serveur dans la console Firebase .

Si vous souhaitez supprimer une ancienne clé de serveur existante, vous pouvez le faire dans Google Cloud Console .

Autoriser les requêtes HTTP

Une demande de message se compose de deux parties : l'en-tête HTTP et le corps HTTP. L'en-tête HTTP doit contenir les en-têtes suivants :

  • Authorization : key=YOUR_SERVER_KEY
    Assurez-vous qu'il s'agit de la clé du serveur , dont la valeur est disponible dans l'onglet Cloud Messaging du volet Paramètres de la console Firebase. Android, la plate-forme Apple et les clés de navigateur sont rejetées par FCM.
  • Content-Type : application/json pour JSON ; application/x-www-form-urlencoded;charset=UTF-8 pour le texte brut.
    Si Content-Type est omis, le format est supposé être du texte brut.

Par exemple:

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

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

Voir Construire des demandes d'envoi pour plus de détails sur la création de demandes d'envoi. La référence du protocole HTTP hérité fournit une liste de tous les paramètres que votre message peut contenir.

Vérification de la validité d'une clé de serveur

Si vous recevez des erreurs d'authentification lors de l'envoi de messages, vérifiez la validité de votre clé de serveur. Par exemple, sous Linux, exécutez la commande suivante :

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

Si vous recevez un code d'état HTTP 401, votre clé de serveur n'est pas valide.

Autoriser une connexion XMPP

Avec XMPP, vous pouvez maintenir une connexion persistante, asynchrone et bidirectionnelle aux serveurs FCM. La connexion peut être utilisée pour envoyer et recevoir des messages entre votre serveur et les appareils connectés à FCM de vos utilisateurs.

Vous pouvez utiliser la plupart des bibliothèques XMPP pour gérer une connexion de longue durée à FCM. Le point de terminaison XMPP s'exécute sur fcm-xmpp.googleapis.com:5235 . Lorsque vous testez des fonctionnalités avec des utilisateurs hors production, vous devez plutôt vous connecter au serveur de préproduction à l' fcm-xmpp.googleapis.com:5236 (notez le port différent).

Des tests réguliers sur la pré-production (un environnement plus petit où les dernières versions de FCM s'exécutent) sont bénéfiques pour isoler les utilisateurs réels du code de test. Les appareils de test et le code de test se connectant à fcm-xmpp.googleapis.com:5236 doivent utiliser un ID d'expéditeur FCM différent pour éviter tout risque d'envoi de messages de test aux utilisateurs de production ou d'envoi de messages en amont à partir du trafic de production via des connexions de test.

La connexion a deux exigences importantes :

  • Vous devez initier une connexion TLS (Transport Layer Security). Notez que FCM ne prend actuellement pas en charge l' extension STARTTLS .
  • FCM requiert un mécanisme d'authentification SASL PLAIN utilisant <your_FCM_Sender_Id>@fcm.googleapis.com ( ID d'expéditeur FCM) et la clé du serveur comme mot de passe. Ces valeurs sont disponibles dans l'onglet Cloud Messaging du volet Paramètres de la console Firebase.

Si à un moment quelconque la connexion échoue, vous devez immédiatement vous reconnecter. Il n'est pas nécessaire de reculer après une déconnexion qui se produit après l'authentification. Pour chaque identifiant d'expéditeur , FCM autorise 2 500 connexions en parallèle.

Les extraits de code suivants illustrent comment effectuer l'authentification et l'autorisation pour une connexion XMPP à FCM.

Serveur XMPP

Le serveur XMPP demande une connexion à FCM

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

FCM

FCM ouvre la connexion et demande un mécanisme d'authentification, y compris la méthode 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>

Serveur XMPP

Le serveur XMPP doit répondre à l'aide de la méthode d'authentification PLAIN , en fournissant la clé du serveur à partir de l'onglet Cloud Messaging du volet Paramètres de la console Firebase.

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

FCM

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

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

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

Remarque : FCM n'utilise pas la ressource liée lors du routage des messages.

Voir Construire des demandes d'envoi pour plus de détails sur la création de demandes d'envoi. La référence du protocole Legacy XMPP fournit une liste de tous les paramètres que votre message peut contenir.