Autoriser les demandes d'envoi

Les demandes 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 API HTTP obsolète et l’autorisation de l’API 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 anciens protocoles obsolètes 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

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

  • Informations d'identification 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 informations d'identification par défaut de l'application (ADC). ADC utilise votre compte de service par défaut existant pour obtenir les informations d'identification permettant d'autoriser les demandes, et ADC permet des tests locaux flexibles via la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS . Pour l’automatisation la plus complète du flux d’autorisation, utilisez ADC avec les bibliothèques du 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 aux fichiers, 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'exposition de vos informations d'identification.

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

Les informations d'identification par défaut de l'application Google (ADC) vérifient vos informations d'identification 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 utiliser aucune des informations d’identification ci-dessus, le système génère une erreur.

L’exemple de code du SDK Admin 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 informations d'identification 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.

Noeud.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 d'un environnement approuvé. 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 une 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 du fichier JSON qui contient la clé de votre compte de service. Cette variable s'applique uniquement à 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) sont capables de déterminer implicitement vos informations d'identification, vous permettant d'utiliser les informations d'identification du compte de service lors des tests ou de l'exécution dans des environnements non Google.

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

Sauf si vous utilisez le SDK Admin , qui gère automatiquement les autorisations, vous devrez créer le jeton d'accès et l'ajouter pour envoyer des requêtes.

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

noeud.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.refresh();
  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> :

noeud.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;

Autoriser les requêtes d'envoi de protocoles hérités

Avec l'ancien protocole HTTP, chaque requête doit contenir la clé du 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 anciennes clés de serveur

À partir de mars 2020, FCM a arrêté de créer des clés de serveur héritées. Les anciennes clés de serveur existantes continueront de fonctionner, mais nous vous recommandons d'utiliser plutôt la version la plus récente de la clé intitulée Clé du serveur dans la console Firebase .

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

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. Les clés Android, Apple et du 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 Créer 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érifier 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é 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 les 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 en pré-production (un environnement plus petit où s'exécutent les dernières versions de FCM) 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 nécessite un mécanisme d'authentification SASL PLAIN utilisant <your_FCM_Sender_Id>@fcm.googleapis.com (FCM sender ID ) 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 donné 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 ID d'expéditeur , FCM autorise 2 500 connexions en parallèle.

Les extraits 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 depuis 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 Créer 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.