Anleitungen

Browser-Push-Benachrichtigungen – Von Null bis Absturz in allen Browsern

Browser-Push-Benachrichtigungen – Von Null bis Absturz in allen Browsern

Haben Sie sich schon einmal jedes Mal geärgert, wenn Sie manuell prüfen mussten, ob Ihr neuer Artikel veröffentlicht wurde? Oder möchten Sie Abonnenten über neue Inhalte informieren, ohne dass sie die Website zuerst öffnen müssen? Nun, das ist das Problem, das ich mit diesem Plugin lösen möchte.

Browser-Push-Benachrichtigung ist eine Technologie, die es Websites ermöglicht, Benachrichtigungen direkt an den Browser des Benutzers zu senden – ähnlich wie Benachrichtigungen von Mobiltelefonanwendungen, jedoch einfach über den Browser. Auf dem Desktop werden Benachrichtigungen in der unteren rechten Ecke angezeigt. Unter iOS sieht es wie eine normale Anwendungsbenachrichtigung aus. Und das Coole: Benutzer müssen die Website nicht zuerst öffnen.

Grundlegende Web-Push-Konzepte

Bevor ich das Plugin bespreche, möchte ich Ihnen ein wenig über die Funktionsweise der Web Push API erzählen. Hier gibt es drei Akteure:

  1. Anwendungsserver – unser Server (PHP, Node.js usw.), der Benachrichtigungen sendet
  2. Push Service – Infrastruktur von Google (FCM), Apple (APNs), Microsoft (WNS) oder Mozilla als Vermittler
  3. Browser/Gerät – wo Benachrichtigungen angezeigt werden

Der Ablauf ist wie folgt: Unser Server verschlüsselt die Benachrichtigungsnutzlast, sendet sie an den Push-Dienst, der Push-Dienst leitet sie an den Browser weiter, der Browser entschlüsselt ihn mithilfe des beim Abonnieren gespeicherten Schlüssels und zeigt dann die Benachrichtigung über den Service Worker an.

Was es schwierig macht: Diese Verschlüsselung muss dem RFC 8291-Standard entsprechen – unter Verwendung der ECDH-Schlüsselvereinbarung, der HKDF-Schlüsselableitung und AES-128-GCM. Wenn die Verschlüsselung nur ein Byte beträgt, kann der Browser nicht entschlüsseln und die Benachrichtigung wird nicht angezeigt. Das habe ich selbst bei der Entwicklung des Plugins erlebt.

Warum reicht natives PHP nicht aus?

Im ersten Versuch habe ich die Verschlüsselung mit reinem PHP implementiert – openssl_pkey_derive(), hash_hmac() für HKDF, openssl_encrypt() für AES-GCM. Alle lokalen Tests bestehen: Verschlüsselung → Entschlüsselungsübereinstimmung. Beim Senden an den ursprünglichen Browser wurde die Benachrichtigung jedoch nicht angezeigt. Große Null. Totalausfall.

Das Problem? Ich habe vergessen, AAD (Additional Authenticated Data) an die AES-GCM-Funktion zu übergeben. AAD ist der Header der verschlüsselten Nutzlast selbst – Salt, Datensatzgröße und Schlüsselkennung. Ohne entsprechendes AAD kann der Browser das Authentifizierungs-Tag nicht validieren, daher ist event.data im Service Worker null und die Benachrichtigung wird nicht angezeigt.

Lektion: Web-Push-Verschlüsselung ist kompliziert. Ein falsches Byte in AAD, alle Browser können es nicht entschlüsseln. Schließlich habe ich die Node.js-Bibliothek web-push verwendet, die von Millionen von Entwicklern getestet wurde, und auf PHP zurückgegriffen, wenn Node.js nicht verfügbar ist.

Push-Browser-Plugin-Architektur

Dieses Plugin führt nicht nur eine Verschlüsselung durch. Es gibt mehrere miteinander verbundene Komponenten:

1. Servicemitarbeiter

Die sw.js-Datei wird im Stammverzeichnis der Website bereitgestellt. Die Aufgabe: Push-Ereignisse vom Browser erfassen, die JSON-Nutzlast analysieren und dann Benachrichtigungen mithilfe der showNotification()-API anzeigen. Verarbeitet auch Benachrichtigungsklickereignisse – zum Beispiel das Öffnen des betreffenden Artikels.

2. Seitenleisten-Widgets

Schaltfläche zum Abonnieren/Abmelden, die in der Blog-Seitenleiste angezeigt wird. Wenn darauf geklickt wird, wird der Benutzer um eine Benachrichtigungserlaubnis gebeten und dann über pushManager.subscribe() den Push-Dienst abonniert. Der öffentliche Schlüssel (VAPID-Schlüssel) ist direkt in das Javascript-Widget eingebettet, sodass kein zusätzlicher Abruf erforderlich ist.

3. Admin-Dashboard

Auf dem CMS-Dashboard gibt es eine Push-Benachrichtigungsseite, die Statistiken anzeigt: Anzahl der aktiven Abonnenten, Benachrichtigungsverlauf und eine Schaltfläche „Test senden“ zum Senden manueller Benachrichtigungen. Es gibt auch eine Einstellungsseite zum Konfigurieren von VAPID-Schlüsseln.

4. Dual-Path-Verschlüsselung

Die Funktion, auf die ich am meisten stolz bin: Das Plugin erkennt automatisch, ob Node.js verfügbar ist oder nicht. Wenn ja, verwenden Sie die web-push-Bibliothek (die getestet wurde). Wenn es nicht vorhanden ist (z. B. Shared Hosting wie Hostinger), greift es automatisch auf PHP Curl + benutzerdefinierte Verschlüsselung zurück. Beide erzeugen gültige verschlüsselte Nutzlasten – getestet für alle fünf Push-Dienste (Apple APNs, Google FCM, Microsoft WNS, Mozilla Autopush und Samsung).

Die anstrengende Reise des Debuggens

Das ist der Teil, an den ich mich am meisten erinnere. Als ich es zum ersten Mal getestet habe, habe ich eine Benachrichtigung an mein iPhone gesendet – der Server hat „gesendet: 5, fehlgeschlagen: 0“ zurückgegeben. Aber die Benachrichtigung erscheint nicht. Ich denke, es ist ein Browser- oder Betriebssystemproblem. Es stellt sich heraus...

  • Erstens: Dem VAPID-Schlüssel fehlt das Präfix 0x04 (unkomprimierter EC-Punkt). Fix: Schlüssel neu generieren.
  • Zweitens: openssl_pkey_get_private() benötigt das PEM-Format, keinen rohen d-Wert. Fix: Privaten Schlüssel als PEM in der Datenbank speichern.
  • Drittens: AAD ist leer. Fix: AAD gemäß RFC 8188 hinzugefügt.
  • Viertens: Apple APNs benötigen den Content-Encoding: aes128gcm-Header. Fix: Header hinzugefügt.
  • Fünftens: Die web-push v3.6.7-Bibliothek verfügt über eine Verbindungsregression zu Apple APNs (ETIMEDOUT). Fix: An v3.4.5 anpinnen + --dns-result-order=ipv4first setzen.

Stellen Sie sich fünf verschiedene Fehler vor, die das Erscheinen von Benachrichtigungen verhindern. Und das Debuggen jedes Einzelnen dauerte Stunden. Aber als ich endlich die Benachrichtigung „Node.js Test“ auf meinem iPhone sah, war ich... wirklich zufrieden.

Installation und Konfiguration

Dieses Plugin ist im Jyavani Plugin Store und GitHub verfügbar. So installieren Sie:

# 1. Download atau clone dari GitHub
git clone https://github.com/adammuizweb/browser-push.git
cp -r browser-push /var/www/anda/plugins/browser-push

# 2. Install Node.js dependencies (opsional, untuk encryption path yang lebih reliable)
cd plugins/browser-push && npm install

# 3. Generate VAPID keys
php plugins/browser-push/generate-vapid.php

# 4. Tambahkan VAPID keys ke database
#    push_vapid_public_key, push_vapid_private_key, push_vapid_subject

# 5. Aktifkan plugin dari Admin → Plugin Manager

Wenn Sie Node.js nicht auf dem Server haben, ist das kein Problem. Das Plugin läuft weiterhin mit PHP-Fallback – alle Funktionen sind gleich, nur der Verschlüsselungspfad ist anders.

Schlussfolgerung

Die Erstellung dieses Push-Benachrichtigungs-Browser-Plugins war eine der intensivsten Programmiererfahrungen, die ich je gemacht habe. Nicht weil es logisch komplex wäre, sondern weil der Web Push-Verschlüsselungsstandard sehr streng ist – ein falsches Byte wird von allen Browsern abgelehnt.

Jetzt wurde dieses Plugin auf fünf verschiedenen Push-Diensten getestet, unterstützt Dual Path (Node.js + PHP) und vor allem: funktioniert wirklich. Sie können selbst sehen, wie es funktioniert, indem Sie sich über das Widget in der Seitenleiste dieses Artikels anmelden. Klicken Sie auf „Abonnieren“, lassen Sie Benachrichtigungen zu und Sie erhalten jedes Mal eine Benachrichtigung, wenn es einen neuen Artikel gibt.

Der Quellcode für dieses Plugin ist Open Source auf GitHub. Bitte forken, anpassen oder das Problem melden. Wenn Sie Fragen haben, schreiben Sie diese in die Kommentare.