Back

Implémentation des notifications push avec l'API Web Push

Implémentation des notifications push avec l'API Web Push

Les notifications push maintiennent l’engagement des utilisateurs même lorsqu’ils n’utilisent pas activement votre application web. L’API Web Push vous permet d’envoyer des mises à jour en temps opportun directement sur les appareils des utilisateurs sans dépendre de services tiers. Ce guide explique comment implémenter des notifications de type natif en utilisant les Service Workers, l’authentification VAPID et un chiffrement approprié.

Points clés à retenir

  • L’API Web Push permet des notifications push natives sans services tiers
  • Les Service Workers et l’authentification VAPID sont des composants essentiels
  • Une connexion HTTPS est obligatoire pour l’implémentation
  • Les différents navigateurs ont des exigences variables pour les notifications push

Prérequis et compatibilité des navigateurs

Avant d’implémenter les notifications push, assurez-vous que votre application répond à ces exigences :

  • Connexion HTTPS (requise pour les Service Workers)
  • Compatibilité avec les navigateurs modernes (Chrome, Firefox, Edge, Safari 16.4+)
  • Compatibilité avec les Service Workers
// Détection des fonctionnalités
if ('serviceWorker' in navigator && 'PushManager' in window) {
  // Les notifications push sont supportées
}

Enregistrement d’un Service Worker

Le Service Worker agit comme un proxy entre votre application web et les services push. Enregistrez-le lors du chargement de la page :

navigator.serviceWorker.register('/sw.js')
  .then(registration => {
    console.log('Service Worker registered:', registration);
  })
  .catch(error => {
    console.error('Registration failed:', error);
  });

Configuration des clés VAPID

VAPID (Voluntary Application Server Identification) authentifie votre serveur auprès des services push. Générez une paire de clés une seule fois pour votre application :

# En utilisant la bibliothèque web-push (Node.js)
npm install web-push
npx web-push generate-vapid-keys

Stockez la clé privée en toute sécurité sur votre serveur et utilisez la clé publique dans votre abonnement côté client.

Création d’abonnements push

Demandez l’autorisation et abonnez les utilisateurs aux notifications push :

async function subscribeToPush() {
  const registration = await navigator.serviceWorker.ready;
  
  // Demander la permission (uniquement sur un geste utilisateur)
  const permission = await Notification.requestPermission();
  if (permission !== 'granted') return;
  
  // S'abonner avec la clé publique VAPID
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
  });
  
  // Envoyer l'abonnement à votre serveur
  await fetch('/api/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription)
  });
}

// Fonction utilitaire pour convertir base64 en Uint8Array
function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding)
    .replace(/\-/g, '+')
    .replace(/_/g, '/');
  
  const rawData = window.atob(base64);
  const outputArray = new Uint8Array(rawData.length);
  
  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
}

L’objet d’abonnement contient :

  • Endpoint : URL unique pour l’envoi de messages
  • Keys : Clés de chiffrement (p256dh et auth) pour la sécurité de la charge utile

Implémentation côté serveur

Votre serveur doit chiffrer les messages et les envoyer au point de terminaison du service push. L’utilisation de la bibliothèque web-push simplifie cette tâche :

const webpush = require('web-push');

webpush.setVapidDetails(
  'mailto:your-email@example.com',
  VAPID_PUBLIC_KEY,
  VAPID_PRIVATE_KEY
);

// Envoyer une notification
const payload = JSON.stringify({
  title: 'New Message',
  body: 'You have a new update',
  icon: '/icon-192.png',
  url: 'https://example.com/updates'
});

webpush.sendNotification(subscription, payload, {
  TTL: 86400, // 24 heures
  urgency: 'high'
})
  .catch(error => {
    console.error('Error sending notification:', error);
  });

Gestion des événements push dans le Service Worker

Le Service Worker reçoit et affiche les notifications push :

// sw.js
self.addEventListener('push', event => {
  const data = event.data?.json() || {};
  
  const options = {
    body: data.body || 'Default message',
    icon: data.icon || '/icon.png',
    badge: '/badge.png',
    vibrate: [200, 100, 200],
    data: { url: data.url }
  };
  
  event.waitUntil(
    self.registration.showNotification(data.title || 'Notification', options)
  );
});

// Gérer les clics sur les notifications
self.addEventListener('notificationclick', event => {
  event.notification.close();
  
  event.waitUntil(
    clients.openWindow(event.notification.data?.url || '/')
  );
});

Exigences spécifiques aux navigateurs

Les différents navigateurs imposent des exigences variables pour l’implémentation de l’API Web Push :

  • Chrome/Edge : Nécessitent des notifications visibles pour chaque message push
  • Firefox : Autorise un push silencieux limité avec un système de quota
  • Safari : Nécessite des notifications visibles et ne prend pas en charge le push silencieux

Remarque : Les tailles de charge utile sont limitées : Chrome/Edge/Firefox prennent en charge jusqu’à 4 Ko, tandis que Safari prend en charge 2 Ko. Gardez les messages légers et récupérez des données supplémentaires dans l’application si nécessaire.

Affichez toujours les notifications immédiatement lors de la réception d’événements push pour maintenir les autorisations sur tous les navigateurs.

Bonnes pratiques de sécurité

Protégez votre implémentation de notifications push :

  1. Sécuriser les points de terminaison : N’exposez jamais publiquement les points de terminaison d’abonnement
  2. Chiffrer les charges utiles : Toutes les données de message doivent utiliser le chiffrement ECDH
  3. Protéger les clés VAPID : Stockez-les en toute sécurité et ne les régénérez qu’en cas de compromission
  4. Implémenter une protection CSRF : Validez les demandes d’abonnement
  5. Limitation de débit : Prévenez les abus avec une limitation côté serveur

Gestion du cycle de vie des abonnements

Gérez les changements et l’expiration des abonnements :

// Dans le Service Worker
self.addEventListener('pushsubscriptionchange', event => {
  event.waitUntil(
    self.registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
    })
      .then(subscription => {
        // Mettre à jour le serveur avec le nouvel abonnement
        return fetch('/api/update-subscription', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(subscription)
        });
      })
  );
});

Conclusion

L’API Web Push fournit une approche basée sur des standards pour implémenter des notifications push sans dépendance à un fournisseur. En combinant les Service Workers, l’authentification VAPID et un chiffrement approprié, vous pouvez délivrer des notifications en temps opportun qui fonctionnent sur les navigateurs modernes. N’oubliez pas de respecter les préférences des utilisateurs, de gérer les événements du cycle de vie des abonnements et de suivre les exigences spécifiques à chaque plateforme pour une implémentation robuste.

Commencez par la livraison de notifications de base, puis ajoutez des fonctionnalités comme les boutons d’action, les pièces jointes d’images et le regroupement de notifications au fur et à mesure que votre implémentation mûrit.

FAQ

Non, les notifications push nécessitent une connexion Internet active pour recevoir des messages du service push. Cependant, les Service Workers peuvent mettre en cache les notifications et les afficher lorsque la connectivité revient.

Lorsque l'autorisation est refusée, vous ne pouvez pas envoyer de notifications push à cet utilisateur. Vous devez attendre qu'il modifie manuellement les autorisations dans les paramètres du navigateur. Envisagez d'implémenter des méthodes d'engagement alternatives comme les notifications dans l'application.

La plupart des services push limitent la taille de la charge utile à 4 Ko. Chrome et Firefox prennent en charge jusqu'à 4 Ko, tandis que Safari prend en charge jusqu'à 2 Ko. Gardez les charges utiles minimales et récupérez des données supplémentaires lors de la réception de la notification si nécessaire.

Oui, les notifications push peuvent être reçues lorsque le navigateur est fermé sur la plupart des plateformes. Cependant, cela dépend du système d'exploitation et du navigateur. Les navigateurs mobiles peuvent avoir des restrictions basées sur les paramètres d'optimisation de la batterie.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay