Start · Sprachen · JavaScript · Referenz · PushSubscription.getKey()

PushSubscription.getKey()

Methode

Gibt einen öffentlichen Client-Schlüssel des Push-Abonnements als <code>ArrayBuffer</code> zurück, z. B. <code>p256dh</code> oder <code>auth</code>, die der Server zur Verschlüsselung braucht.

seit JavaScript Baseline: alle modernen Browser (Safari ab 16 auf Kategorie: webapi

Signatur

PushSubscription.prototype.getKey(name)

Beschreibung

Die Methode getKey() des PushSubscription-Objekts liefert das Schlüsselmaterial, mit dem ein Push-Server Nachrichten nach RFC 8291 (Message Encryption for Web Push) für genau dieses Abonnement verschlüsseln kann. Ohne diese Schlüssel kann der Server keine Push-Nachricht mit Nutzdaten senden, die der Browser entschlüsseln kann.

Es gibt zwei Schlüsselnamen:

  • "p256dh": der öffentliche ECDH-Schlüssel des Clients auf der Kurve P-256 (unkomprimierter Punkt, 65 Byte).
  • "auth": ein zufälliges Authentifizierungsgeheimnis (16 Byte), das in die Schlüsselableitung eingeht.

Typischerweise liest man beide Schlüssel direkt nach pushManager.subscribe() aus, wandelt sie in Base64url um und schickt sie zusammen mit dem endpoint an den eigenen Server. Oft ist subscription.toJSON() der einfachere Weg, weil dort die Schlüssel schon Base64url-kodiert unter keys.p256dh und keys.auth stehen. getKey() braucht man, wenn man die rohen Bytes haben will, etwa um sie zu prüfen oder selbst zu kodieren.

Parameter

Name Typ Default Beschreibung
$name Pflicht "p256dh" | "auth" Name des gewünschten Schlüssels: "p256dh" für den öffentlichen ECDH-Schlüssel (P-256) oder "auth" für das Authentifizierungsgeheimnis.

Rückgabewert

Typ
ArrayBuffer | null
Beschreibung
Ein ArrayBuffer mit den rohen Schlüsselbytes oder null, wenn für diesen Namen kein Schlüssel vorhanden ist.

Beispiele

Schlüssel nach dem Abonnieren auslesen

// Läuft im Hauptthread, der Service Worker muss bereits registriert sein
const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
});

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

console.log(p256dh.byteLength, auth.byteLength);
65 16

Schlüssel Base64url-kodiert an den Server senden

const toBase64Url = (buffer) => {
  const bytes = new Uint8Array(buffer);
  const binary = String.fromCharCode(...bytes);
  return btoa(binary)
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
};

const sendSubscriptionToServer = async (subscription) => {
  const payload = {
    endpoint: subscription.endpoint,
    keys: {
      p256dh: toBase64Url(subscription.getKey('p256dh')),
      auth: toBase64Url(subscription.getKey('auth'))
    }
  };

  const response = await fetch('/api/push/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload)
  });
  if (!response.ok) throw new Error(`Speichern fehlgeschlagen: ${response.status}`);
};

const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.getSubscription();
if (subscription) await sendSubscriptionToServer(subscription);

Vergleich mit toJSON()

const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.getSubscription();

if (subscription) {
  const { keys } = subscription.toJSON();
  // toJSON() liefert dieselben Schlüssel bereits Base64url-kodiert
  console.log(typeof keys.p256dh, typeof keys.auth);
  console.log(subscription.getKey('p256dh') instanceof ArrayBuffer);
}
string string true

// Wichtig · Fallstricke

  • Kodierung: Web-Push-Bibliotheken auf dem Server (z. B. web-push für Node.js) erwarten die Schlüssel als Base64url ohne Padding und nicht als normales Base64. Wenn man btoa() direkt verwendet, ohne +, / und = zu ersetzen, schlägt die Verschlüsselung auf dem Server oft ohne klare Fehlermeldung fehl.
  • Ungültiger Name: Ein anderer Name als "p256dh" oder "auth" führt zu einem TypeError, weil der Parameter ein IDL-Enum ist.
  • Vertraulichkeit: auth ist ein gemeinsames Geheimnis. Übertragen Sie es nur per HTTPS und speichern Sie es auf dem Server geschützt. Wer es zusammen mit dem Endpoint kennt, kann dem Nutzer Push-Nachrichten schicken, die der Browser als gültig annimmt.
  • Kompatibilität: Die Push-API gibt es nur in sicheren Kontexten (HTTPS) und nur mit registriertem Service Worker. Unter iOS/iPadOS funktioniert sie erst ab 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden.
  • Aktualität: Abonnements können ablaufen oder vom Browser erneuert werden, dann ändern sich auch die Schlüssel. Übertragen Sie die Schlüssel nach jeder Änderung neu, etwa im Service Worker beim Event pushsubscriptionchange.