Nous avons vu comment une bibliothèque peut être utilisée pour déclencher des messages push, mais que font exactement ces bibliothèques ?
Ils effectuent des requêtes réseau tout en s'assurant qu'elles sont au bon format. La spécification qui définit cette requête réseau est le protocole Web Push.
Cette section explique comment le serveur peut s'identifier avec des clés de serveur d'application et comment la charge utile chiffrée et les données associées sont envoyées.
Ce n'est pas le côté le plus agréable des notifications Web push, et je ne suis pas un expert en chiffrement, mais examinons chaque élément, car il est utile de savoir ce que font ces bibliothèques en coulisses.
Clés de serveur d'application
Lorsque nous abonnons un utilisateur, nous transmettons un applicationServerKey. Cette clé est transmise au service de notification push et utilisée pour vérifier que l'application qui a abonné l'utilisateur est également celle qui déclenche les messages push.
Lorsque nous déclenchons un message push, nous envoyons un ensemble d'en-têtes qui permettent au service push d'authentifier l'application. (Cette valeur est définie par la spécification VAPID.)
Qu'est-ce que cela signifie concrètement et que se passe-t-il exactement ? Voici les étapes suivies pour l'authentification du serveur d'application :
- Le serveur d'application signe certaines informations JSON avec sa clé privée d'application.
- Ces informations signées sont envoyées au service de notification push sous la forme d'un en-tête dans une requête POST.
- Le service de notification push utilise la clé publique stockée qu'il a reçue de
pushManager.subscribe()pour vérifier que les informations reçues sont signées par la clé privée associée à la clé publique. Rappel : La clé publique est leapplicationServerKeytransmis à l'appel d'abonnement. - Si les informations signées sont valides, le service de notification push envoie le message push à l'utilisateur.
Vous trouverez ci-dessous un exemple de ce flux d'informations. (Notez la légende en bas à gauche qui indique les clés publiques et privées.)
Les "informations signées" ajoutées à un en-tête de la requête sont un jeton Web JSON.
Jeton Web JSON
Un jeton Web JSON (ou JWT) est un moyen d'envoyer un message à un tiers de sorte que le destinataire puisse valider l'identité de l'expéditeur.
Lorsqu'un tiers reçoit un message, il doit obtenir la clé publique de l'expéditeur et l'utiliser pour valider la signature du jeton JWT. Si la signature est valide, le jeton JWT doit avoir été signé avec la clé privée correspondante et doit donc provenir de l'expéditeur attendu.
De nombreuses bibliothèques sur jwt.io/ peuvent effectuer la signature pour vous. Je vous recommande de les utiliser dans la mesure du possible. Pour être complet, voyons comment créer manuellement un jeton JWT signé.
Notifications Web Push et jetons JWT signés
Un jeton JWT signé n'est qu'une chaîne, bien qu'il puisse être considéré comme trois chaînes jointes par des points.
Les première et deuxième chaînes (informations et données JWT) sont des éléments JSON encodés en base64, ce qui signifie qu'elles sont lisibles publiquement.
La première chaîne contient des informations sur le jeton JWT lui-même, indiquant l'algorithme utilisé pour créer la signature.
Les informations JWT pour les notifications Web push doivent contenir les informations suivantes :
{
"typ": "JWT",
"alg": "ES256"
}
La deuxième chaîne correspond aux données JWT. Il fournit des informations sur l'expéditeur du jeton JWT, le destinataire et la durée de validité.
Pour les notifications Web push, les données se présenteraient comme suit :
{
"aud": "https://some-push-service.org",
"exp": "1469618703",
"sub": "mailto:example@web-push-book.org"
}
La valeur aud correspond à l'audience, c'est-à-dire à qui le jeton JWT est destiné. Pour le push Web, l'audience est le service de notification push. Nous la définissons donc sur l'origine du service de notification push.
La valeur exp correspond à l'expiration du jeton JWT. Cela empêche les espions de réutiliser un jeton JWT s'ils l'interceptent. L'expiration est un code temporel en secondes et ne doit pas dépasser 24 heures.
Dans Node.js, l'expiration est définie à l'aide de :
Math.floor(Date.now() / 1000) + 12 * 60 * 60;
La durée est de 12 heures au lieu de 24 heures pour éviter tout problème lié aux différences d'heure entre l'application d'envoi et le service de notification push.
Enfin, la valeur sub doit être une URL ou une adresse e-mail mailto.
Cela permet au service de notification push de trouver les coordonnées de l'expéditeur dans le jeton JWT s'il a besoin de le contacter. (C'est pourquoi la bibliothèque Web Push avait besoin d'une adresse e-mail.)
Tout comme les informations JWT, les données JWT sont encodées sous la forme d'une chaîne base64 sécurisée pour les URL.
La troisième chaîne, la signature, est le résultat de la combinaison des deux premières chaînes (informations JWT et données JWT) avec un point, que nous appellerons le "jeton non signé", et de sa signature.
Le processus de signature nécessite le chiffrement du jeton non signé à l'aide d'ES256. Selon la spécification JWT, ES256 est l'abréviation de "ECDSA utilisant la courbe P-256 et l'algorithme de hachage SHA-256". Avec Web Crypto, vous pouvez créer la signature comme suit :
// Utility function for UTF-8 encoding a string to an ArrayBuffer.
const utf8Encoder = new TextEncoder('utf-8');
// The unsigned token is the concatenation of the URL-safe base64 encoded
// header and body.
const unsignedToken = .....;
// Sign the |unsignedToken| using ES256 (SHA-256 over ECDSA).
const key = {
kty: 'EC',
crv: 'P-256',
x: window.uint8ArrayToBase64Url(
applicationServerKeys.publicKey.subarray(1, 33)),
y: window.uint8ArrayToBase64Url(
applicationServerKeys.publicKey.subarray(33, 65)),
d: window.uint8ArrayToBase64Url(applicationServerKeys.privateKey),
};
// Sign the |unsignedToken| with the server's private key to generate
// the signature.
return crypto.subtle.importKey('jwk', key, {
name: 'ECDSA', namedCurve: 'P-256',
}, true, ['sign'])
.then((key) => {
return crypto.subtle.sign({
name: 'ECDSA',
hash: {
name: 'SHA-256',
},
}, key, utf8Encoder.encode(unsignedToken));
})
.then((signature) => {
console.log('Signature: ', signature);
});
Un service de notifications push peut valider un jeton JWT à l'aide de la clé publique du serveur d'application pour déchiffrer la signature et s'assurer que la chaîne déchiffrée est identique au "jeton non signé" (c'est-à-dire les deux premières chaînes du jeton JWT).
Le jeton JWT signé (c'est-à-dire les trois chaînes jointes par des points) est envoyé au service Web Push en tant qu'en-tête Authorization avec WebPush ajouté au début, comme suit :
Authorization: 'WebPush [JWT Info].[JWT Data].[Signature]';
Le protocole Web Push indique également que la clé de serveur d'application publique doit être envoyée dans l'en-tête Crypto-Key sous forme de chaîne encodée en base64 sécurisée pour les URL, avec p256ecdsa= ajouté au début.
Crypto-Key: p256ecdsa=[URL Safe Base64 Public Application Server Key]
Chiffrement de la charge utile
Voyons maintenant comment envoyer une charge utile avec un message push afin que notre application Web puisse accéder aux données qu'elle reçoit.
Une question fréquente se pose pour ceux qui ont utilisé d'autres services de notifications push : pourquoi la charge utile des notifications push Web doit-elle être chiffrée ? Avec les applications natives, les messages push peuvent envoyer des données en texte brut.
L'un des avantages des notifications push Web est que, comme tous les services push utilisent la même API (le protocole Web Push), les développeurs n'ont pas à se soucier de l'identité du service push. Nous pouvons envoyer une requête au bon format et nous attendre à ce qu'un message push soit envoyé. L'inconvénient est que les développeurs pourraient envoyer des messages à un service push qui n'est pas fiable. En chiffrant la charge utile, un service de notification push ne peut pas lire les données envoyées. Seul le navigateur peut déchiffrer les informations. Cela permet de protéger les données de l'utilisateur.
Le chiffrement de la charge utile est défini dans la spécification de chiffrement des messages.
Avant d'examiner les étapes spécifiques pour chiffrer la charge utile d'un message push, nous devons aborder certaines techniques qui seront utilisées lors du processus de chiffrement. (Un grand merci à Mat Scales pour son excellent article sur le chiffrement push.)
ECDH et HKDF
ECDH et HKDF sont utilisés tout au long du processus de chiffrement et offrent des avantages pour le chiffrement des informations.
ECDH : échange de clés Elliptic Curve Diffie-Hellman
Imaginons qu'Alice et Bob souhaitent partager des informations. Alice et Bob possèdent chacun leurs propres clés publiques et privées. Alice et Bob partagent leurs clés publiques.
La propriété utile des clés générées avec ECDH est qu'Alice peut utiliser sa clé privée et la clé publique de Bob pour créer la valeur secrète "X". Bob peut faire de même en utilisant sa clé privée et la clé publique d'Alice pour créer indépendamment la même valeur X. Cela fait de "X" un secret partagé, et Alice et Bob n'ont eu qu'à partager leur clé publique. Robert et Alice peuvent désormais utiliser "X" pour chiffrer et déchiffrer les messages qu'ils s'envoient.
À ma connaissance, ECDH définit les propriétés des courbes qui permettent cette "fonctionnalité" de créer un secret partagé X.
Il s'agit d'une explication générale de l'algorithme ECDH. Si vous souhaitez en savoir plus, je vous recommande de regarder cette vidéo plus détaillée sur l'algorithme ECDH.
En termes de code, la plupart des langages et plates-formes sont fournis avec des bibliothèques permettant de générer facilement ces clés.
Dans le nœud, nous allons procéder comme suit :
const keyCurve = crypto.createECDH('prime256v1');
keyCurve.generateKeys();
const publicKey = keyCurve.getPublicKey();
const privateKey = keyCurve.getPrivateKey();
HKDF : fonction de dérivation de clé basée sur HMAC
Wikipedia propose une description succincte de HKDF :
HKDF est une fonction de dérivation de clé basée sur HMAC qui transforme tout matériel de clé faible en matériel de clé cryptographiquement fort. Il peut être utilisé, par exemple, pour convertir les secrets partagés échangés par Diffie Hellman en matériel de clé adapté à une utilisation dans le chiffrement, la vérification de l'intégrité ou l'authentification.
En résumé, HKDF prendra une entrée qui n'est pas particulièrement sécurisée et la rendra plus sécurisée.
La spécification définissant ce chiffrement exige l'utilisation de SHA-256 comme algorithme de hachage. Les clés HKDF résultantes pour les notifications push Web ne doivent pas dépasser 256 bits (32 octets).
Dans le nœud, cela peut être implémenté comme suit :
// Simplified HKDF, returning keys up to 32 bytes long
function hkdf(salt, ikm, info, length) {
// Extract
const keyHmac = crypto.createHmac('sha256', salt);
keyHmac.update(ikm);
const key = keyHmac.digest();
// Expand
const infoHmac = crypto.createHmac('sha256', key);
infoHmac.update(info);
// A one byte long buffer containing only 0x01
const ONE_BUFFER = new Buffer(1).fill(1);
infoHmac.update(ONE_BUFFER);
return infoHmac.digest().slice(0, length);
}
Merci à Mat Scale pour cet exemple de code.
Cela couvre de manière générale ECDH et HKDF.
ECDH est un moyen sécurisé de partager des clés publiques et de générer une clé secrète partagée. HKDF est un moyen de sécuriser des éléments non sécurisés.
Elle sera utilisée lors du chiffrement de notre charge utile. Voyons maintenant ce que nous prenons comme entrée et comment elle est chiffrée.
Entrées
Lorsque nous souhaitons envoyer un message push à un utilisateur avec une charge utile, nous avons besoin de trois entrées :
- La charge utile elle-même.
- Le secret
authdePushSubscription. - Clé
p256dhdePushSubscription.
Nous avons constaté que les valeurs auth et p256dh étaient récupérées à partir d'un PushSubscription. Pour rappel, voici les valeurs dont nous avons besoin pour un abonnement :
subscription.toJSON().keys.auth;
subscription.toJSON().keys.p256dh;
subscription.getKey('auth');
subscription.getKey('p256dh');
La valeur auth doit être traitée comme un secret et ne doit pas être partagée en dehors de votre application.
La clé p256dh est une clé publique, parfois appelée clé publique du client. Ici, nous ferons référence à p256dh comme clé publique de l'abonnement. La clé publique de l'abonnement est générée par le navigateur. Le navigateur gardera la clé privée secrète et l'utilisera pour déchiffrer la charge utile.
Ces trois valeurs, auth, p256dh et payload, sont nécessaires en tant qu'entrées. Le résultat du processus de chiffrement sera la charge utile chiffrée, une valeur de salt et une clé publique utilisée uniquement pour chiffrer les données.
Salt
Le sel doit être composé de 16 octets de données aléatoires. Dans NodeJS, nous allons créer un sel comme suit :
const salt = crypto.randomBytes(16);
Clés publiques / privées
Les clés publiques et privées doivent être générées à l'aide d'une courbe elliptique P-256, comme suit dans Node :
const localKeysCurve = crypto.createECDH('prime256v1');
localKeysCurve.generateKeys();
const localPublicKey = localKeysCurve.getPublicKey();
const localPrivateKey = localKeysCurve.getPrivateKey();
Nous les appelons "clés locales". Elles sont utilisées uniquement pour le chiffrement et n'ont rien à voir avec les clés de serveur d'application.
Avec la charge utile, le secret d'authentification et la clé publique de l'abonnement comme entrées, ainsi qu'un sel et un ensemble de clés locales nouvellement générés, nous sommes prêts à effectuer un chiffrement.
Secret partagé
La première étape consiste à créer une clé secrète partagée à l'aide de la clé publique de l'abonnement et de notre nouvelle clé privée (vous vous souvenez de l'explication sur ECDH avec Alice et Bob ? C'est aussi simple que ça !
const sharedSecret = localKeysCurve.computeSecret(
subscription.keys.p256dh,
'base64',
);
Elle sera utilisée à l'étape suivante pour calculer la clé pseudo-aléatoire (PRK).
Clé pseudo-aléatoire
La clé pseudo-aléatoire (PRK) est la combinaison du secret d'authentification de l'abonnement push et du secret partagé que nous venons de créer.
const authEncBuff = new Buffer('Content-Encoding: auth\0', 'utf8');
const prk = hkdf(subscription.keys.auth, sharedSecret, authEncBuff, 32);
Vous vous demandez peut-être à quoi sert la chaîne Content-Encoding: auth\0.
En bref, il n'a pas d'objectif clair, même si les navigateurs peuvent déchiffrer un message entrant et rechercher l'encodage de contenu attendu.
\0 ajoute un octet avec une valeur de 0 à la fin du tampon. C'est ce que les navigateurs attendent pour déchiffrer le message. Ils s'attendent à ce qu'il y ait autant d'octets pour l'encodage du contenu, suivis d'un octet de valeur 0, puis des données chiffrées.
Notre clé pseudo-aléatoire exécute simplement l'authentification, le secret partagé et un élément d'informations d'encodage via HKDF (c'est-à-dire en le rendant cryptographiquement plus fort).
Contexte
Le "contexte" est un ensemble d'octets utilisé pour calculer deux valeurs plus tard dans le navigateur de chiffrement. Il s'agit essentiellement d'un tableau d'octets contenant la clé publique de l'abonnement et la clé publique locale.
const keyLabel = new Buffer('P-256\0', 'utf8');
// Convert subscription public key into a buffer.
const subscriptionPubKey = new Buffer(subscription.keys.p256dh, 'base64');
const subscriptionPubKeyLength = new Uint8Array(2);
subscriptionPubKeyLength[0] = 0;
subscriptionPubKeyLength[1] = subscriptionPubKey.length;
const localPublicKeyLength = new Uint8Array(2);
subscriptionPubKeyLength[0] = 0;
subscriptionPubKeyLength[1] = localPublicKey.length;
const contextBuffer = Buffer.concat([
keyLabel,
subscriptionPubKeyLength.buffer,
subscriptionPubKey,
localPublicKeyLength.buffer,
localPublicKey,
]);
Le tampon de contexte final est un libellé, le nombre d'octets de la clé publique de l'abonnement, suivi de la clé elle-même, puis du nombre d'octets de la clé publique locale, suivi de la clé elle-même.
Avec cette valeur de contexte, nous pouvons l'utiliser pour créer un nonce et une clé de chiffrement de contenu (CEK).
Clé de chiffrement du contenu et nonce
Un nonce est une valeur qui empêche les attaques par relecture, car elle ne doit être utilisée qu'une seule fois.
La clé de chiffrement du contenu (CEK) est la clé qui sera finalement utilisée pour chiffrer notre charge utile.
Nous devons d'abord créer les octets de données pour le nonce et la clé CEK, qui sont simplement une chaîne d'encodage de contenu suivie du tampon de contexte que nous venons de calculer :
const nonceEncBuffer = new Buffer('Content-Encoding: nonce\0', 'utf8');
const nonceInfo = Buffer.concat([nonceEncBuffer, contextBuffer]);
const cekEncBuffer = new Buffer('Content-Encoding: aesgcm\0');
const cekInfo = Buffer.concat([cekEncBuffer, contextBuffer]);
Ces informations sont traitées par HKDF, qui combine le sel et le PRK avec nonceInfo et cekInfo :
// The nonce should be 12 bytes long
const nonce = hkdf(salt, prk, nonceInfo, 12);
// The CEK should be 16 bytes long
const contentEncryptionKey = hkdf(salt, prk, cekInfo, 16);
Nous obtenons ainsi notre nonce et notre clé de chiffrement du contenu.
Effectuer le chiffrement
Maintenant que nous avons notre clé de chiffrement de contenu, nous pouvons chiffrer la charge utile.
Nous créons un chiffrement AES128 en utilisant la clé de chiffrement du contenu comme clé, et le nonce est un vecteur d'initialisation.
Dans Node, cela se fait comme suit :
const cipher = crypto.createCipheriv(
'id-aes128-GCM',
contentEncryptionKey,
nonce,
);
Avant de chiffrer notre charge utile, nous devons définir la quantité de remplissage que nous souhaitons ajouter au début de la charge utile. L'intérêt d'ajouter un remplissage est d'éviter que des espions puissent déterminer les "types" de messages en fonction de la taille de la charge utile.
Vous devez ajouter deux octets de marge intérieure pour indiquer la longueur de toute marge intérieure supplémentaire.
Par exemple, si vous n'avez ajouté aucun remplissage, vous aurez deux octets de valeur 0 (c'est-à-dire qu'il n'y a pas de remplissage). Après ces deux octets, vous lirez la charge utile. Si vous avez ajouté cinq octets de remplissage, les deux premiers octets auront une valeur de 5. Le consommateur lira ensuite cinq octets supplémentaires, puis commencera à lire la charge utile.
const padding = new Buffer(2 + paddingLength);
// The buffer must be only zeros, except the length
padding.fill(0);
padding.writeUInt16BE(paddingLength, 0);
Nous exécutons ensuite notre marge intérieure et notre charge utile via ce chiffrement.
const result = cipher.update(Buffer.concat(padding, payload));
cipher.final();
// Append the auth tag to the result -
// https://nodejs.org/api/crypto.html#crypto_cipher_getauthtag
const encryptedPayload = Buffer.concat([result, cipher.getAuthTag()]);
Nous avons maintenant notre charge utile chiffrée. Super !
Il ne reste plus qu'à déterminer comment cette charge utile est envoyée au service de notification push.
En-têtes et corps de charge utile chiffrés
Pour envoyer cette charge utile chiffrée au service de notification push, nous devons définir quelques en-têtes différents dans notre requête POST.
En-tête de chiffrement
L'en-tête "Chiffrement" doit contenir le sel utilisé pour chiffrer la charge utile.
Le sel de 16 octets doit être encodé en base64 sécurisé pour les URL et ajouté à l'en-tête de chiffrement, comme suit :
Encryption: salt=[URL Safe Base64 Encoded Salt]
En-tête Crypto-Key
Nous avons vu que l'en-tête Crypto-Key est utilisé dans la section "Clés du serveur d'application" pour contenir la clé publique du serveur d'application.
Cet en-tête est également utilisé pour partager la clé publique locale utilisée pour chiffrer la charge utile.
L'en-tête obtenu se présente comme suit :
Crypto-Key: dh=[URL Safe Base64 Encoded Local Public Key String]; p256ecdsa=[URL Safe Base64 Encoded Public Application Server Key]
En-têtes de type de contenu, de longueur et d'encodage
L'en-tête Content-Length correspond au nombre d'octets de la charge utile chiffrée. Les en-têtes "Content-Type" et "Content-Encoding" sont des valeurs fixes.
C'est ce qui est illustré ci-dessous.
Content-Length: [Number of Bytes in Encrypted Payload]
Content-Type: 'application/octet-stream'
Content-Encoding: 'aesgcm'
Une fois ces en-têtes définis, nous devons envoyer la charge utile chiffrée en tant que corps de notre requête. Notez que Content-Type est défini sur application/octet-stream. En effet, la charge utile chiffrée doit être envoyée sous forme de flux d'octets.
Dans NodeJS, vous procéderiez comme suit :
const pushRequest = https.request(httpsOptions, function(pushResponse) {
pushRequest.write(encryptedPayload);
pushRequest.end();
D'autres en-têtes ?
Nous avons abordé les en-têtes utilisés pour les clés JWT / de serveur d'application (c'est-à-dire comment identifier l'application avec le service push) et les en-têtes utilisés pour envoyer une charge utile chiffrée.
Les services de notification push utilisent d'autres en-têtes pour modifier le comportement des messages envoyés. Certains de ces en-têtes sont obligatoires, tandis que d'autres sont facultatifs.
En-tête TTL
Obligatoire
TTL (ou valeur TTL (Time To Live)) est un entier qui spécifie le nombre de secondes pendant lesquelles vous souhaitez que votre message push reste sur le service de notification push avant d'être distribué. Lorsque le TTL expire, le message est supprimé de la file d'attente du service de notifications push et n'est pas distribué.
TTL: [Time to live in seconds]
Si vous définissez une valeur TTL égale à zéro, le service de notification push tentera de distribuer le message immédiatement, mais si l'appareil est injoignable, votre message sera immédiatement supprimé de la file d'attente du service de notification push.
Techniquement, un service de notification push peut réduire le TTL d'un message push s'il le souhaite. Pour savoir si cela s'est produit, examinez l'en-tête TTL dans la réponse d'un service push.
Sujet
Optional
Les sujets sont des chaînes qui peuvent être utilisées pour remplacer un message en attente par un nouveau message s'ils ont des noms de sujet identiques.
Cela est utile dans les scénarios où plusieurs messages sont envoyés lorsqu'un appareil est hors connexion, et où vous ne souhaitez que l'utilisateur voie le dernier message lorsque l'appareil est allumé.
Urgence
Optional
L'urgence indique au service de notifications push l'importance d'un message pour l'utilisateur. Le service de notifications push peut utiliser cette fonctionnalité pour préserver l'autonomie de la batterie de l'appareil d'un utilisateur en ne l'activant que pour les messages importants lorsque la batterie est faible.
La valeur de l'en-tête est définie comme indiqué ci-dessous. La valeur par défaut est normal.
Urgency: [very-low | low | normal | high]
Tout au même endroit
Si vous avez d'autres questions sur le fonctionnement de tout cela, vous pouvez toujours consulter la façon dont les bibliothèques déclenchent les messages push sur l'organisation web-push-libs.
Une fois que vous disposez d'une charge utile chiffrée et des en-têtes ci-dessus, il vous suffit d'envoyer une requête POST à endpoint dans un PushSubscription.
Que faisons-nous de la réponse à cette requête POST ?
Réponse du service de notification push
Une fois que vous avez envoyé une requête à un service de notification push, vous devez vérifier le code d'état de la réponse pour savoir si la requête a abouti ou non.
| Code d'état | Description |
|---|---|
| 201 | Création terminée La demande d'envoi d'un message push a été reçue et acceptée. |
| 429 | Trop de requêtes. Cela signifie que votre serveur d'application a atteint une limite de fréquence avec un service de notification push. Le service de notification push doit inclure un en-tête "Retry-After" (Réessayer après) pour indiquer le délai avant qu'une autre requête puisse être effectuée. |
| 400 | Demande incorrecte. Cela signifie généralement que l'un de vos en-têtes n'est pas valide ou est mal formaté. |
| 404 | Introuvable. Cela indique que l'abonnement a expiré et ne peut pas être utilisé. Dans ce cas, vous devez supprimer l'objet `PushSubscription` et attendre que le client réabonne l'utilisateur. |
| 410 | aux frustrations. L'abonnement n'est plus valide et doit être supprimé du serveur d'applications. Pour reproduire ce problème, appelez `unsubscribe()` sur un `PushSubscription`. |
| 413 | La taille de la charge utile est trop importante. La taille de charge utile minimale qu'un service de notification push doit prendre en charge est de 4 096 octets (ou 4 ko). |
Pour en savoir plus sur les codes d'état HTTP, vous pouvez également consulter la norme Web Push (RFC8030).
Étapes suivantes
- Présentation des notifications push Web
- Fonctionnement des notifications push
- S'abonner à un utilisateur
- Expérience utilisateur des autorisations
- Envoyer des messages avec les bibliothèques Web Push
- Protocole Web Push
- Gérer les événements push
- Afficher une notification
- Comportement des notifications
- Modèles de notification courants
- Questions fréquentes sur les notifications push
- Problèmes courants et signalement de bugs