Web Push-Protokoll

Matt Gaunt

Wir haben gesehen, wie eine Bibliothek zum Auslösen von Push-Mitteilungen verwendet werden kann. Was genau machen diese Bibliotheken?

Sie stellen Netzwerkanfragen und achten dabei darauf, dass diese Anfragen das richtige Format haben. Die Spezifikation, die diese Netzwerkanfrage definiert, ist die Web-Push-Protokoll.

Diagramm zum Senden einer Push-Nachricht von Ihrem Server an eine Push-Nachricht
Dienst

In diesem Abschnitt wird beschrieben, wie sich der Server mit Anwendungsserverschlüsseln identifizieren kann und wie die verschlüsselte Nutzlast und die zugehörigen Daten gesendet werden.

Das ist nicht die schöne Seite von Web Push und ich bin kein Experte für Verschlüsselung, aber sehen wir uns die einzelnen Teile an, da es praktisch ist zu wissen, was diese Bibliotheken im Hintergrund tun.

Anwendungsserverschlüssel

Wenn wir einen Nutzer abonnieren, übergeben wir ein applicationServerKey. Dieser Schlüssel wird an den Push-Dienst übergeben und verwendet, um zu prüfen, ob die Anwendung, die den Nutzer abonniert hat, auch die Anwendung ist, die Push-Nachrichten auslöst.

Wenn wir eine Push-Nachricht auslösen, senden wir eine Reihe von Headern, Push-Dienst die Anwendung zu authentifizieren. (Dies ist definiert als gemäß der VAPID-Spezifikation)

Was bedeutet das eigentlich und was geschieht genau? Das sind die Schritte, Anwendungsserver-Authentifizierung:

  1. Der Anwendungsserver signiert einige JSON-Informationen mit seinem privaten Anwendungsschlüssel.
  2. Diese signierten Informationen werden als Header in einer POST-Anfrage an den Push-Dienst gesendet.
  3. Der Push-Dienst verwendet den gespeicherten öffentlichen Schlüssel, den er von pushManager.subscribe() erhalten hat, um zu prüfen, ob die empfangenen Informationen mit dem privaten Schlüssel signiert wurden, der mit dem öffentlichen Schlüssel verknüpft ist. Denken Sie daran: Der öffentliche Schlüssel ist die applicationServerKey, die an den subscribe-Aufruf übergeben wird.
  4. Wenn die signierten Informationen gültig sind, sendet der Push-Dienst die Push-Nachricht an den Nutzer.

Unten finden Sie ein Beispiel für diesen Informationsfluss. In der Legende unten links sehen Sie, öffentlichen und privaten Schlüsseln.)

Darstellung, wie der private Anwendungsserverschlüssel beim Senden eines
Nachricht

Die „signierten Informationen“ dem Header in der Anfrage hinzugefügt wird, ist ein JSON Web Token.

JSON-Webtoken

Ein JSON-Web-Token (kurz JWT) ist eine Möglichkeit, eine Nachricht an Dritte zu senden, damit der Empfänger prüfen kann, wer sie gesendet hat.

Wenn Dritte eine Nachricht erhalten, müssen sie die Absender öffentlichen Schlüssels und überprüfen damit die Signatur des JWT. Wenn der Parameter Signatur ist gültig, muss das JWT mit dem übereinstimmenden privater Schlüssel, d. h. muss vom erwarteten Absender stammen.

Auf https://jwt.io/ finden Sie eine Vielzahl von Bibliotheken, die die Signatur für Sie ausführen können. Ich würde Ihnen empfehlen, diese Möglichkeit nach Möglichkeit zu nutzen. Zur Vollständigkeit sehen wir uns an, wie Sie ein signiertes JWT manuell erstellen.

Webpush und signierte JWTs

Ein signiertes JWT ist nur ein String, auch wenn man sich drei Strings vorstellen kann, die miteinander verbunden sind. Punkte.

Abbildung der Strings in einer JSON-Webversion
Token

Der erste und zweite String (JWT-Informationen und JWT-Daten) sind JSON-Elemente, die base64-codiert sind und daher öffentlich lesbar sind.

Der erste String enthält Informationen zum JWT selbst und gibt an, mit welchem Algorithmus die Signatur erstellt wurde.

Die JWT-Informationen für Web-Push müssen die folgenden Informationen enthalten:

{
  "typ": "JWT",
  "alg": "ES256"
}

Der zweite String sind die JWT-Daten. Sie liefert Informationen zum Sender des JWT, ist und wie lange sie gültig ist.

Bei Web-Push-Nachrichten haben die Daten folgendes Format:

{
  "aud": "https://some-push-service.org",
  "exp": "1469618703",
  "sub": "mailto:example@web-push-book.org"
}

Der Wert aud ist die „Zielgruppe“, d.h. für wen das JWT bestimmt ist. Bei Web-Push ist die Zielgruppe der Push-Dienst. Daher wird sie auf den Ursprung des Push-Dienstes festgelegt.

Der Wert exp ist das Ablaufdatum des JWT. So wird verhindert, dass Angreifer ein JWT wiederverwenden können, wenn sie es abfangen. Die Ablaufzeit ist ein Zeitstempel in Sekunden und darf nicht mehr 24 Stunden betragen.

In Node.js wird die Ablaufzeit so festgelegt:

Math.floor(Date.now() / 1000) + 12 * 60 * 60;

Es sind 12 Stunden statt 24 Stunden, um Probleme mit Zeitabweichungen zwischen der sendenden Anwendung und dem Push-Dienst zu vermeiden.

Schließlich muss der Wert sub entweder eine URL oder eine mailto-E-Mail-Adresse sein. So kann ein Push-Dienst den Absender kontaktieren, Kontaktinformationen aus dem JWT. (Aus diesem Grund benötigte die Web-Push-Bibliothek eine E-Mail-Adresse.)

Genau wie die JWT-Informationen werden die JWT-Daten als URL-sicherer Base64-String codiert.

Der dritte String, die Signatur, ist das Ergebnis der Zusammenführung der ersten beiden Strings (JWT-Informationen und JWT-Daten) mit einem Punktzeichen, das wir als „unsigniertes Token“ bezeichnen, und der Signatur.

Beim Signaturvorgang muss das „nicht signierte Token“ verschlüsselt werden mit ES256. Gemäß JWT steht, steht ES256 für „ECDSA mit der P-256-Kurve“ und SHA-256-Hash-Algorithmus“. Mit Web-Kryptografie können Sie die Signatur so erstellen:

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

Ein Push-Dienst kann ein JWT mit dem öffentlichen Schlüssel des Anwendungsservers validieren, um die Signatur zu entschlüsseln und dafür zu sorgen, dass der entschlüsselte String mit dem „unsignierten Token“ übereinstimmt (d. h. den ersten beiden Strings im JWT).

Das signierte JWT (d. h. alle drei Strings, die durch Punkte verbunden sind) wird als Authorization-Header mit vorangestelltem WebPush an den Web-Push-Dienst gesendet:

Authorization: 'WebPush [JWT Info].[JWT Data].[Signature]';

Das Web Push-Protokoll besagt außerdem, dass der öffentliche Schlüssel des Anwendungsservers im Crypto-Key-Header als URL-sicherer Base64-codierter String gesendet werden muss, dem p256ecdsa= vorangestellt ist.

Crypto-Key: p256ecdsa=[URL Safe Base64 Public Application Server Key]

Nutzlastverschlüsselung

Sehen wir uns als Nächstes an, wie wir eine Nutzlast mit einer Push-Nachricht senden können, damit unsere Webanwendung, wenn sie eine Push-Nachricht empfängt, auf die empfangenen Daten zugreifen kann.

Wer bereits andere Push-Dienste verwendet hat, stellt sich häufig die Frage, warum das Web Nutzlast verschlüsselt werden? Bei nativen Apps können Push-Nachrichten Daten als Nur-Text senden.

Das Schöne an Web-Push ist, dass alle Push-Dienste das API (Web-Push-Protokoll) verwenden, ist es für Entwickler nicht wichtig, Push-Dienst ist. Wir können eine Anfrage im richtigen Format stellen und erwarten Push-Nachricht zu senden. Der Nachteil ist, dass Entwickler Nachrichten an einen Push-Dienst senden, der nicht vertrauenswürdig ist. Durch die Verschlüsselung der Nutzlast kann ein Push-Dienst die gesendeten Daten nicht lesen. Nur der Browser kann die Informationen entschlüsseln. So wird die Daten.

Die Verschlüsselung der Nutzlast ist in der Spezifikation für die Nachrichtenverschlüsselung definiert.

Bevor wir uns die spezifischen Schritte zum Verschlüsseln einer Nutzlast von Push-Nachrichten ansehen, sollten wir einige Techniken behandeln, die bei der Verschlüsselung . (Vielen Dank an Mat Scales für seinen hervorragenden Artikel zur Push-Verschlüsselung.)

ECDH und HKDF

Sowohl ECDH als auch HKDF werden während des gesamten Verschlüsselungsprozesses verwendet und bieten Vorteile für die der Verschlüsselung von Informationen.

ECDH: Elliptic Curve Diffie-Hellman-Schlüsselaustausch

Angenommen, es gibt zwei Personen, die Informationen teilen möchten: Alice und Bob. Sowohl Alice als auch Bob haben eigene öffentliche und private Schlüssel. Alice und Bob geben ihre öffentlichen Schlüssel einander bekannt.

Die nützliche Eigenschaft von mit ECDH generierten Schlüsseln besteht darin, dass Alice ihren privaten Schlüssel und den öffentlichen Schlüssel von Bob verwenden kann, um den geheimen Wert „X“ zu erstellen. Bob kann dasselbe tun und mit seinem privaten Schlüssel und dem öffentlichen Schlüssel von Alice unabhängig denselben Wert „X“ erstellen. Dadurch wird „X“ zu einem gemeinsamen Geheimnis und Alice und Bob mussten nur ihren öffentlichen Schlüssel teilen. Jetzt können Bob und Alice „X“ verwenden, um Nachrichten zwischen ihnen zu verschlüsseln und zu entschlüsseln.

ECDH definiert nach meinem besten Wissen die Eigenschaften von Kurven, die dieses „Merkmal“ ermöglichen. eines gemeinsamen Secrets „X“.

Dies ist eine allgemeine Erläuterung des ECDH. Weitere Informationen findest du in diesem Video.

Was den Code angeht: die meisten Sprachen / Plattformen mit Bibliotheken ausgestattet sind, diese Schlüssel einfach zu generieren.

Im Knoten würden wir Folgendes tun:

const keyCurve = crypto.createECDH('prime256v1');
keyCurve.generateKeys();

const publicKey = keyCurve.getPublicKey();
const privateKey = keyCurve.getPrivateKey();

HKDF: HMAC-basierte Schlüsselableitungsfunktion

Wikipedia hat eine kurze Beschreibung von HKDF:

HKDF ist eine HMAC-basierte Schlüsselableitungsfunktion, die beliebiges schwaches Schlüsselmaterial in kryptografisch starkes Schlüsselmaterial umwandelt. Sie kann verwendet werden, Um die von Diffie Hellman ausgetauschten geheimen Schlüssel in Schlüsselmaterial umzuwandeln, Geeignet für die Verschlüsselung, Integritätsprüfung oder Authentifizierung.

Im Grunde genommen nimmt HKDF eine Eingabe, die nicht besonders sicher ist, und macht sie sicherer.

Gemäß der Spezifikation, durch die diese Verschlüsselung definiert wird, muss SHA-256 als Hash-Algorithmus verwendet werden Die resultierenden Schlüssel für HKDF in Web-Push sollten nicht länger als 256 Bit sein. (32 Byte).

Im Knoten könnte dies so implementiert werden:

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

Dieser Beispielcode basiert auf dem Artikel von Mat Scale.

Hiermit wird ECDH lose behandelt. und HKDF.

Mit ECDH können Sie öffentliche Schlüssel sicher freigeben und ein gemeinsames Secret generieren. HKDF ist eine Möglichkeit, unsicheres Material und sichern.

Diese wird während der Verschlüsselung unserer Nutzlast verwendet. Als Nächstes sehen wir uns an, was wir als Eingabe verwenden und wie diese verschlüsselt wird.

Eingaben

Wenn wir eine Push-Nachricht mit einer Nutzlast an einen Nutzer senden möchten, sind drei Eingaben erforderlich:

  1. Die Nutzlast selbst.
  2. Das auth-Secret aus dem PushSubscription.
  3. Den p256dh-Schlüssel von PushSubscription.

Die Werte auth und p256dh werden aus einer PushSubscription abgerufen, Zur Erinnerung: Bei einem Abo benötigen wir folgende Werte:

subscription.toJSON().keys.auth;
subscription.toJSON().keys.p256dh;

subscription.getKey('auth');
subscription.getKey('p256dh');

Der auth-Wert sollte als geheim behandelt und nicht außerhalb Ihrer Anwendung weitergegeben werden.

Der Schlüssel p256dh ist ein öffentlicher Schlüssel, der manchmal auch als öffentlicher Clientschlüssel bezeichnet wird. Hier nennen wir p256dh als öffentlichen Aboschlüssel. Der öffentliche Aboschlüssel wird vom Browser generiert. Der Browser hält den privaten Schlüssel geheim und verwendet ihn zum Entschlüsseln der Nutzlast.

Diese drei Werte, auth, p256dh und payload, sind als Eingaben erforderlich. Das Ergebnis des Verschlüsselungsprozesses ist die verschlüsselte Nutzlast, ein Salt-Wert und ein öffentlicher Schlüssel, der nur zum Verschlüsseln der Daten verwendet wird.

Salt

Der Salt muss aus 16 Byte zufälligen Daten bestehen. In NodeJS würden wir Folgendes tun, um ein Salt zu erstellen:

const salt = crypto.randomBytes(16);

Öffentliche/private Schlüssel

Der öffentliche und der private Schlüssel sollten mit einer elliptischen P-256-Kurve generiert werden. In Node.js würden wir das so tun:

const localKeysCurve = crypto.createECDH('prime256v1');
localKeysCurve.generateKeys();

const localPublicKey = localKeysCurve.getPublicKey();
const localPrivateKey = localKeysCurve.getPrivateKey();

Diese Schlüssel werden als „lokale Schlüssel“ bezeichnet. Sie werden nur zur Verschlüsselung verwendet und nichts mit Anwendungsserverschlüsseln zu tun.

Mit der Nutzlast, dem Authentifizierungsgeheimnis und dem öffentlichen Aboschlüssel als Eingabe und mit einem neu generierten Salt und einen Satz lokaler Schlüssel haben, sind wir bereit für die Verschlüsselung.

Gemeinsames Secret

Der erste Schritt besteht darin, ein gemeinsames Secret mit dem öffentlichen Aboschlüssel und dem neuen privaten Schlüssel (erinnern Sie sich an die ECDH-Erklärung mit Alice und Bob? einfach so).

const sharedSecret = localKeysCurve.computeSecret(
  subscription.keys.p256dh,
  'base64',
);

Dieser wird im nächsten Schritt verwendet, um den Pseudozufallsschlüssel (PRK) zu berechnen.

Pseudozufälliger Schlüssel

Der Pseudozufallsschlüssel (PRK) ist die Kombination aus dem Authentifizierungssecret des Push-Abos und dem gerade erstellten gemeinsamen Secret.

const authEncBuff = new Buffer('Content-Encoding: auth\0', 'utf8');
const prk = hkdf(subscription.keys.auth, sharedSecret, authEncBuff, 32);

Sie fragen sich vielleicht, wozu der String Content-Encoding: auth\0 dient. Es hat also keinen eindeutigen Zweck, obwohl Browser eine eingehende Nachricht entschlüsseln und nach der erwarteten Inhaltscodierung suchen. \0 fügt dem Ende des Zwischenspeichers ein Byte mit dem Wert 0 hinzu. Das wird von Browsern erwartet, die die Nachricht entschlüsseln. Sie erwarten so viele Bytes für die Inhaltscodierung, gefolgt von einem Byte mit dem Wert 0 und dann von den verschlüsselten Daten.

Bei unserem Pseudozufallsschlüssel werden lediglich die Authentifizierung, der gemeinsame geheime Schlüssel und ein Teil der Codierungsinformationen ausgeführt. über HKDF übertragen (d.h. sie kryptografisch stärker machen).

Kontext

Der „Kontext“ ist eine Reihe von Bytes, mit denen später im Verschlüsselungsbrowser zwei Werte berechnet werden. Es ist im Wesentlichen ein Array von Bytes, das den öffentlichen Aboschlüssel und den lokalen öffentlichen Schlüssel.

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,
]);

Der letzte Kontextpuffer ist ein Label, die Anzahl der Byte im öffentlichen Aboschlüssel, gefolgt vom Schlüssel selbst, der Anzahl der Byte des lokalen öffentlichen Schlüssels, gefolgt vom Schlüssel selbst.

Mit diesem Kontextwert können wir einen Nonce und einen Inhaltsverschlüsselungsschlüssel (Content Encryption Key, CEK) erstellen.

Schlüssel und Nonce für die Inhaltsverschlüsselung

Eine Nonce ist ein Wert, der die Wiederholung verhindert. da sie nur einmal verwendet werden sollten.

Der Content Encryption Key (CEK) ist der Schlüssel, mit dem unsere Nutzlast verschlüsselt wird.

Zuerst müssen wir die Datenbytes für den Nonce und den CEK erstellen. Das ist einfach ein String zur Inhaltscodierung, gefolgt vom gerade berechneten Kontextbuffer:

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

Diese Informationen werden durch HKDF geleitet, wobei das Salz und der PRK mit den nonceInfo und cekInfo kombiniert werden:

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

So erhalten wir den Nonce und den Inhaltsverschlüsselungsschlüssel.

Verschlüsselung durchführen

Nachdem wir den Inhaltsverschlüsselungsschlüssel haben, können wir die Nutzlast verschlüsseln.

Wir erstellen eine AES128-Chiffre mit dem Inhaltsverschlüsselungsschlüssel als Schlüssel und der Nonce ist ein Initialisierungsvektor.

In Node geht das so:

const cipher = crypto.createCipheriv(
  'id-aes128-GCM',
  contentEncryptionKey,
  nonce,
);

Bevor wir die Nutzlast verschlüsseln, müssen wir festlegen, wie viel Padding der Nutzlast hinzugefügt werden soll. Wir sollten einen Abstand hinzufügen, dass verhindert wird, dass Unbefugte die "Typen" basierend auf der Nutzlastgröße.

Sie müssen zwei Bytes für das Padding hinzufügen, um die Länge des zusätzlichen Paddings anzugeben.

Wenn Sie beispielsweise kein Padding hinzugefügt haben, haben Sie nach diesen beiden Byte zwei Byte mit dem Wert 0, d.h., es ist kein Padding vorhanden, nachdem Sie die Nutzlast gelesen haben. Wenn Sie 5 Byte Padding hinzugefügt haben, haben die ersten beiden Byte den Wert 5. Der Nutzer liest dann weitere fünf Byte und beginnt dann mit dem Lesen der Nutzlast.

const padding = new Buffer(2 + paddingLength);
// The buffer must be only zeros, except the length
padding.fill(0);
padding.writeUInt16BE(paddingLength, 0);

Anschließend führen wir das Padding und die Nutzlast durch diese Chiffre aus.

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

Jetzt haben wir unsere verschlüsselte Nutzlast. Super!

Jetzt müssen Sie nur noch bestimmen, wie diese Nutzlast an den Push-Dienst gesendet wird.

Verschlüsselte Header und Body der Nutzlast

Um diese verschlüsselte Nutzlast an den Push-Dienst zu senden, müssen wir einige verschiedene Header in unserer POST-Anfrage.

Verschlüsselungsheader

Die „Verschlüsselung“ Der Header muss das salt enthalten, das zum Verschlüsseln der Nutzlast verwendet wird.

Das 16-Byte-Salt muss mit base64 URL-sicher codiert sein und dem Verschlüsselungsheader wie folgt hinzugefügt werden:

Encryption: salt=[URL Safe Base64 Encoded Salt]

Header für kryptografischen Schlüssel

Wir haben gesehen, dass die Crypto-Key-Überschrift im Abschnitt „Application Server Keys“ verwendet wird, um den öffentlichen Schlüssel des Anwendungsservers zu enthalten.

Dieser Header wird auch verwendet, um den lokalen öffentlichen Schlüssel freizugeben, der zum Verschlüsseln der Nutzlast verwendet wird.

Der resultierende Header sieht so aus:

Crypto-Key: dh=[URL Safe Base64 Encoded Local Public Key String]; p256ecdsa=[URL Safe Base64 Encoded Public Application Server Key]

Inhaltstyp, Länge und Codierung von Headern

Der Content-Length-Header ist die Anzahl der Byte in der verschlüsselten Nutzlast. 'Inhaltstyp' und "Content-Encoding" Header sind feste Werte. Das ist unten dargestellt.

Content-Length: [Number of Bytes in Encrypted Payload]
Content-Type: 'application/octet-stream'
Content-Encoding: 'aesgcm'

Wenn diese Header festgelegt sind, müssen wir die verschlüsselte Nutzlast als Textkörper unserer Anfrage. Beachten Sie, dass Content-Type auf application/octet-stream. Das liegt daran, dass die verschlüsselte Nutzlast als Bytestream gesendet werden muss.

In NodeJS würden wir das so machen:

const pushRequest = https.request(httpsOptions, function(pushResponse) {
pushRequest.write(encryptedPayload);
pushRequest.end();

Weitere Überschriften?

Wir haben die Header für JWT-/Anwendungsserverschlüssel behandelt (d. h. wie die Anwendung mit dem Push-Dienst identifiziert wird) und die Header zum Senden einer verschlüsselten Nutzlast.

Es gibt zusätzliche Header, mit denen Push-Dienste das Verhalten gesendeter Nachrichten ändern. Einige dieser Header sind erforderlich, andere optional.

TTL-Header

Erforderlich

TTL (oder Gültigkeitsdauer) ist eine Ganzzahl, die die Anzahl der Sekunden angibt Ihre Push-Nachricht im Push-Dienst zu veröffentlichen, geliefert wurden. Wenn die TTL abläuft, wird die Nachricht aus der Push-Dienstwarteschlange entfernt und nicht zugestellt.

TTL: [Time to live in seconds]

Wenn Sie TTL auf „0“ setzen, versucht der Push-Dienst, die Nachricht sofort zuzustellen. Wenn das Gerät jedoch nicht erreichbar ist, wird die Nachricht sofort aus der Push-Dienstwarteschlange entfernt.

Technisch gesehen kann ein Push-Dienst die TTL einer Push-Nachricht nach Belieben reduzieren. Ob dies der Fall ist, können Sie anhand des TTL-Headers in der Antwort eines Push-Dienstes erkennen.

Thema

Optional

Themen sind Strings, mit denen ausstehende Nachrichten durch eine neue Nachricht ersetzt werden können, wenn sie über übereinstimmende Themennamen verfügen.

Dies ist nützlich in Szenarien, in denen mehrere Nachrichten gesendet werden, während ein Gerät offline ist und Sie möchten, dass die Nutzer nur die aktuellen angezeigt, wenn das Gerät eingeschaltet wird.

Dringlichkeit

Optional

Die Dringlichkeit gibt dem Push-Dienst an, wie wichtig eine Nachricht für den Nutzer ist. So kann der Push-Dienst die Akkulaufzeit des Geräts eines Nutzers verlängern, indem er es nur bei wichtigen Nachrichten weckt, wenn der Akkustand niedrig ist.

Der Headerwert wird wie unten dargestellt definiert. Der Standardwert ist normal

Urgency: [very-low | low | normal | high]

Alles zusammen

Wenn Sie weitere Fragen zur Funktionsweise haben, können Sie jederzeit nachsehen, wie Bibliotheken ausgelöst werden. Push-Nachrichten in der Organisation "web-push-libs"

Sobald du eine verschlüsselte Nutzlast und die oben genannten Header hast, musst du nur noch eine POST-Anfrage an die endpoint in einer PushSubscription senden.

Was machen wir also mit der Antwort auf diese POST-Anfrage?

Antwort vom Push-Dienst

Nachdem Sie eine Anfrage an einen Push-Dienst gesendet haben, müssen Sie den Statuscode der Antwort prüfen. Anhand dieses Codes können Sie erkennen, ob die Anfrage erfolgreich war oder nicht.

Statuscode Beschreibung
201 Erstellt Die Anfrage zum Senden einer Push-Nachricht ist eingegangen und wurde akzeptiert.
429 Zu viele Anfragen: Das bedeutet, dass Ihr Anwendungsserver eine Ratenbeschränkung mit einem Push-Dienst erreicht hat. Der Push-Dienst sollte einen Befehl zum Wiederholen , der angibt, wie lange es dauert, bis eine weitere Anfrage gestellt werden kann.
400 Ungültige Anfrage. Das bedeutet im Allgemeinen, dass einer Ihrer Header ungültig ist. falsch formatiert sind.
404 Nicht gefunden. Das Abo ist abgelaufen und kann nicht mehr verwendet werden. In diesem Fall sollten Sie „PushSubscription“ löschen und warten, bis der Client den Nutzer erneut abonniert.
410 Weg. Das Abo ist nicht mehr gültig und sollte vom Anwendungsserver entfernt werden. Sie können dies reproduzieren, indem Sie `unsubscribe()` für ein `PushSubscription` an.
413 Nutzlastgröße zu groß. Die Mindestgröße der Nutzlast, die ein Push-Dienst unterstützen muss, beträgt 4.096 Byte (oder 4 KB).

Weitere Informationen zu den HTTP-Statuscodes finden Sie im Web Push-Standard (RFC8030).

Weitere Informationen

Code labs