Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Remarque
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 10 de cet article.
Avertissement
Cette version d'ASP.NET Core n'est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 10 de cet article.
Blazor Les PWA peuvent recevoir et afficher des notifications Push (messages de données) à partir d’un serveur principal, même si l’utilisateur n’utilise pas activement l’application. Par exemple, les notifications Push peuvent être envoyées lorsqu’un autre utilisateur effectue une action dans sa PWA installée ou lorsque l’application ou les utilisateurs interagissent directement avec l’application serveur principal effectuent une action.
Utilisez les notifications Push pour :
- Informez les utilisateurs que quelque chose d’important s’est produit, en les invitant à revenir à l’application.
- Mettez à jour les données stockées dans l’application, telles qu’un flux d’actualités, afin que l’utilisateur ait de nouvelles données sur son prochain retour à l’application, même s’il est hors connexion lorsque la notification Push est émise.
Les mécanismes d’envoi, de réception et d’affichage d’une notification Push sont indépendants de Blazor WebAssembly. L’envoi d’une notification Push est implémenté par le serveur principal, qui peut utiliser n’importe quelle technologie. La réception et l’affichage d’une notification Push sur le client sont implémentées dans le fichier JavaScript (JS) du worker de service.
L’exemple de cet article utilise des notifications Push pour fournir des mises à jour de l’état des commandes aux clients d’un restaurant de pizzas basé sur l’application de démonstration PWA Blazing Pizza Workshop. Vous n’êtes pas obligé de participer à l’atelier en ligne pour utiliser cet article, mais l’atelier est une introduction utile au Blazor développement PWA.
Remarque
L’application Blazing Pizza adopte le modèle de référentiel pour créer une couche d’abstraction entre la couche d’interface utilisateur et la couche d’accès aux données. Pour plus d’informations, consultez le modèle Unité de travail (UoW) et Conception de la couche de persistance de l’infrastructure.
Établir des clés publiques et privées
Générez les clés publiques et privées de chiffrement pour sécuriser les notifications Push localement, par exemple avec PowerShell ou IIS, ou à l’aide d’un outil en ligne.
Espaces réservés utilisés dans l’exemple de code de cet article :
-
{PUBLIC KEY}: clé publique. -
{PRIVATE KEY}: clé privée.
Pour les exemples C# de cet article, mettez à jour l’adresse someone@example.com e-mail pour qu’elle corresponde à l’adresse utilisée lors de la création de la paire de clés personnalisée.
Lors de l’implémentation de notifications Push, assurez-vous que les clés de chiffrement sont gérées en toute sécurité :
- Génération de clé : utilisez une bibliothèque ou un outil approuvé pour générer les clés publiques et privées. Évitez d’utiliser des algorithmes faibles ou obsolètes.
- Stockage de clés : stockez des clés privées en toute sécurité sur le serveur, à l’aide d’un mécanisme de stockage sécurisé, tel qu’un module de sécurité matériel (HSM) ou un stockage chiffré. N’exposez jamais de clés privées au client.
- Utilisation de la clé : utilisez la clé privée uniquement pour signer des charges utiles de notification Push. Vérifiez que la clé publique est distribuée en toute sécurité aux clients.
Pour plus d’informations sur les meilleures pratiques de chiffrement, consultez Services de chiffrement.
Création d’un abonnement
Avant d’envoyer des notifications Push à un utilisateur, l’application doit demander l’autorisation à l’utilisateur. S’ils accordent l’autorisation de recevoir des notifications, leur navigateur génère un abonnement, qui inclut un ensemble de jetons que l’application peut utiliser pour acheminer les notifications vers l’utilisateur.
L’autorisation peut être obtenue à tout moment par l’application, mais nous vous recommandons uniquement de demander aux utilisateurs l’autorisation lorsqu’il est clair pourquoi ils voudraient s’abonner aux notifications de l’application. L’exemple suivant interroge les utilisateurs lorsqu’ils arrivent sur la page de paiement (composant Checkout), car à ce stade, il est clair que l’utilisateur envisage sérieusement de passer une commande.
Si l’utilisateur accepte de recevoir des notifications, l’exemple suivant envoie les données d’abonnement de notification Push au serveur, où les jetons de notification Push sont stockés dans la base de données pour une utilisation ultérieure.
Ajoutez un fichier de notifications JS Push pour demander un abonnement :
- Appelez
navigator.serviceWorker.getRegistrationpour obtenir l’enregistrement du service worker. - Appelez
worker.pushManager.getSubscriptionpour déterminer si un abonnement existe. - Si un abonnement n’existe pas, créez un abonnement à l’aide de la
PushManager.subscribefonction et retournez l’URL et les jetons du nouvel abonnement.
Dans l’application Blazing Pizza, le JS fichier est nommé pushNotifications.js et situé dans le dossier des ressources statiques publiques (wwwroot) du projet de bibliothèque de Razor classes de la solution (BlazingPizza.ComponentsLibrary). La blazorPushNotifications.requestSubscription fonction demande un abonnement.
BlazingPizza.ComponentsLibrary/wwwroot/pushNotifications.js :
(function () {
const applicationServerPublicKey = '{PUBLIC KEY}';
window.blazorPushNotifications = {
requestSubscription: async () => {
const worker = await navigator.serviceWorker.getRegistration();
const existingSubscription = await worker.pushManager.getSubscription();
if (!existingSubscription) {
const newSubscription = await subscribe(worker);
if (newSubscription) {
return {
url: newSubscription.endpoint,
p256dh: arrayBufferToBase64(newSubscription.getKey('p256dh')),
auth: arrayBufferToBase64(newSubscription.getKey('auth'))
};
}
}
}
};
async function subscribe(worker) {
try {
return await worker.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerPublicKey
});
} catch (error) {
if (error.name === 'NotAllowedError') {
return null;
}
throw error;
}
}
function arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
})();
Remarque
Pour plus d’informations sur la fonction précédente arrayBufferToBase64 , consultez Comment puis-je convertir un ArrayBuffer en chaîne encodée en base64 ? (Stack Overflow).
Un objet d’abonnement et un point de terminaison d’abonnement de notification sont créés sur le serveur. Le point de terminaison reçoit des appels d’API web client avec des données d’abonnement de notification Push, y compris des jetons de chiffrement. Les données sont stockées dans la base de données pour chaque utilisateur d’application.
Dans l’application Blazing Pizza, l’objet d’abonnement est la NotificationSubscription classe. Les propriétés P256dh et Auth sont les jetons cryptographiques de l'utilisateur.
BlazingPizza.Shared/NotificationSubscription.cs :
public class NotificationSubscription
{
public int? NotificationSubscriptionId { get; set; }
public string? UserId { get; set; }
public string? Url { get; set; }
public string? P256dh { get; set; }
public string? Auth { get; set; }
}
Le notifications/subscribe point de terminaison est défini dans la méthode d’extension de MapPizzaApi l’application, qui est appelée dans le fichier de Program l’application pour configurer des points de terminaison d’API web pour l’application. L’abonnement aux notifications de l’utilisateur (NotificationSubscriptionqui inclut ses jetons de notification Push) est stocké dans la base de données. Un seul abonnement par utilisateur est stocké. Vous pouvez également autoriser l’utilisateur à inscrire plusieurs abonnements à partir de différents navigateurs ou appareils.
app.MapPut("/notifications/subscribe",
[Authorize] async (
HttpContext context,
PizzaStoreContext db,
NotificationSubscription subscription) =>
{
var userId = GetUserId(context);
if (userId is null)
{
return Results.Unauthorized();
}
// Remove old subscriptions for this user
var oldSubscriptions = db.NotificationSubscriptions.Where(
e => e.UserId == userId);
db.NotificationSubscriptions.RemoveRange(oldSubscriptions);
// Store the new subscription
subscription.UserId = userId;
db.NotificationSubscriptions.Add(subscription);
await db.SaveChangesAsync();
return Results.Ok(subscription);
});
Dans BlazingPizza.Client/HttpRepository.cs, la méthode SubscribeToNotifications envoie un HTTP PUT vers l'endpoint des abonnements sur le serveur :
public class HttpRepository : IRepository
{
private readonly HttpClient _httpClient;
public HttpRepository(HttpClient httpClient)
{
_httpClient = httpClient;
}
...
public async Task SubscribeToNotifications(NotificationSubscription subscription)
{
var response = await _httpClient.PutAsJsonAsync("notifications/subscribe",
subscription);
response.EnsureSuccessStatusCode();
}
}
L’interface du référentiel (BlazingPizza.Shared/IRepository.cs) inclut la signature de méthode de SubscribeToNotifications:
public interface IRepository
{
...
Task SubscribeToNotifications(NotificationSubscription subscription);
}
Définissez une méthode pour demander un abonnement et vous abonner aux notifications si l’abonnement est établi. Enregistrez l’abonnement dans la base de données pour une utilisation ultérieure.
Dans le Checkout composant de l’application Blazing Pizza, la RequestNotificationSubscriptionAsync méthode effectue les tâches suivantes :
- L’abonnement est créé via JS interop en appelant
blazorPushNotifications.requestSubscription. Le composant injecte le IJSRuntime service pour appeler la JS fonction. - La
SubscribeToNotificationsméthode est appelée pour enregistrer l’abonnement.
Dans BlazingPizza.Client/Components/Pages/Checkout.razor :
async Task RequestNotificationSubscriptionAsync()
{
var subscription = await JSRuntime.InvokeAsync<NotificationSubscription>(
"blazorPushNotifications.requestSubscription");
if (subscription is not null)
{
try
{
await Repository.SubscribeToNotifications(subscription);
}
catch (AccessTokenNotAvailableException ex)
{
ex.Redirect();
}
}
}
Dans le Checkout composant, RequestNotificationSubscriptionAsync est appelé dans la méthode du cycle de vieOnInitialized et s’exécute lors de l’initialisation des composants. La méthode est asynchrone, mais peut s’exécuter en arrière-plan, et le résultat Task qu’elle retourne peut être ignoré. Par conséquent, la méthode n’est pas appelée dans la méthode de cycle de vie asynchrone pour l’initialisation des composants (OnInitializedAsync). Cette approche rend le composant plus rapide.
protected override void OnInitialized()
{
_ = RequestNotificationSubscriptionAsync();
}
Pour illustrer le fonctionnement du code, exécutez l’application Blazing Pizza et commencez à passer une commande. Accédez à l’écran de paiement pour voir la demande d’abonnement :
Choisissez Autoriser et vérifiez dans la console des outils de développement du navigateur pour vérifier les erreurs. Vous pouvez définir un point d’arrêt dans le code de PizzaApiExtensions de MapPut("/notifications/subscribe"...) et exécuter l'application avec débogage pour inspecter les données entrantes provenant du navigateur. Les données incluent une URL de point de terminaison et des jetons de chiffrement.
Une fois que l’utilisateur a autorisé ou bloqué les notifications pour un site donné, le navigateur ne se demande plus. Pour réinitialiser l’autorisation de test supplémentaire pour Google Chrome ou Microsoft Edge, sélectionnez l’icône « informations » (🛈) à gauche de la barre d’adresse du navigateur et revenez aux notifications pour demander (par défaut), comme indiqué dans l’image suivante :
Envoi d’une notification
L’envoi d’une notification implique l’exécution d’opérations de chiffrement complexes sur le serveur pour protéger les données en transit. La majeure partie de la complexité est gérée pour l’application par un package NuGet tiers, WebPushqui est utilisé par le projet de serveur (BlazingPizza.Server) dans l’application Blazing Pizza.
La SendNotificationAsync méthode distribue les notifications de commande à l’aide de l’abonnement capturé. Le code suivant utilise des WebPush API pour distribuer la notification. La charge utile de la notification est sérialisée JSON et inclut un message et une URL. Le message s’affiche à l’utilisateur et l’URL permet à l’utilisateur d’atteindre la commande de pizza associée à la notification. Des paramètres supplémentaires peuvent être sérialisés comme requis pour d’autres scénarios de notification.
Avertissement
Dans l’exemple suivant, nous vous recommandons d’utiliser une approche sécurisée pour fournir la clé privée. Lorsque vous travaillez localement dans l’environnement Development , une clé privée peut être fournie à l’application à l’aide de l’outil Gestionnaire de secrets . Dans les environnements Development, Staging et Production, Azure Key Vault avec des identités managées Azure peuvent être utilisés. Il est à noter que, pour obtenir la clé privée d’un certificat à partir d’un coffre de clés, le certificat doit avoir une clé privée exportable.
private static async Task SendNotificationAsync(Order order,
NotificationSubscription subscription, string message)
{
var publicKey = "{PUBLIC KEY}";
var privateKey = "{PRIVATE KEY}";
var pushSubscription = new PushSubscription(subscription.Url,
subscription.P256dh, subscription.Auth);
var vapidDetails = new VapidDetails("mailto:<someone@example.com>", publicKey,
privateKey);
var webPushClient = new WebPushClient();
try
{
var payload = JsonSerializer.Serialize(new
{
message,
url = $"myorders/{order.OrderId}",
});
await webPushClient.SendNotificationAsync(pushSubscription, payload,
vapidDetails);
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error sending push notification: {ex.Message}");
}
}
L’exemple précédent permet au serveur d’envoyer des notifications, mais le navigateur ne réagit pas aux notifications sans logique supplémentaire. L’affichage des notifications est abordé dans la section Notifications d’affichage .
La console des outils de développement du navigateur indique l’arrivée des notifications dix secondes après que les commandes sont passées dans l’application Blazing Pizza. Sous l’onglet Application , ouvrez la section Push Messaging . Sélectionnez le cercle pour démarrer l’enregistrement :
Afficher les notifications
Le service worker de la PWA (service-worker.js) doit gérer les notifications push pour que l’application puisse les afficher.
Le gestionnaire d’événement push suivant dans l’application Blazing Pizza appelle showNotification pour créer une notification destinée au service worker actif.
Dans BlazingPizza/wwwroot/service-worker.js :
self.addEventListener('push', event => {
const payload = event.data.json();
event.waitUntil(
self.registration.showNotification('Blazing Pizza', {
body: payload.message,
icon: 'img/icon-512.png',
vibrate: [100, 50, 100],
data: { url: payload.url }
})
);
});
Le code précédent ne prend effet qu’après le chargement de la page suivante, lorsque le navigateur enregistre Installing service worker.... En cas de difficulté à mettre à jour le service worker, utilisez l’onglet Application dans la console des outils de développement du navigateur. Sous Service Workers, choisissez Mettre à jour ou utiliser Annuler l’inscription pour forcer une nouvelle inscription lors du chargement suivant.
Avec le code précédent en place et la nouvelle commande passée par un utilisateur, la commande passe en En cours de livraison après 10 secondes selon la logique de démonstration intégrée de l'application. Le navigateur reçoit une notification Push :
Lorsque vous utilisez l’application dans Google Chrome ou Microsoft Edge, la notification s’affiche même si l’utilisateur n’utilise pas activement l’application Blazing Pizza. Toutefois, le navigateur doit être en cours d’exécution ou la notification s’affiche la prochaine fois que le navigateur est ouvert.
Lorsque vous utilisez la PWA installée, la notification doit être remise même si l’utilisateur n’exécute pas l’application.
Gérer les clics de notification
Inscrivez un gestionnaire d’événementsnotificationclick pour traiter un utilisateur sélectionnant (en cliquant) une notification Push sur son appareil :
- Fermez la notification en appelant
event.notification.close. - Appelez
clients.openWindowpour créer un nouveau contexte de navigation de niveau supérieur et charger l’URL fournie à la méthode.
L’exemple suivant dans l’application Blazing Pizza amène l’utilisateur à la page d’état de commande pour l’ordre qui se rapporte à la notification. L’URL est fournie par le event.notification.data.url paramètre, qui est envoyé par le serveur dans la charge utile de la notification.
Dans le fichier service worker (service-worker.js) :
self.addEventListener('notificationclick', event => {
event.notification.close();
event.waitUntil(clients.openWindow(event.notification.data.url));
});
Si la PWA est installée sur l’appareil, la PWA s’affiche sur l’appareil. Si la PWA n’est pas installée, l’utilisateur est dirigé vers la page de l’application dans son navigateur.