Protokół Web Push Protocol

Widzieliśmy już, jak można używać biblioteki do wyzwalania komunikatów push, ale do czego dokładnie one służą?

Wysyłają żądania sieciowe, a jednocześnie dbają o odpowiedni format. Specyfikacją definiującą to żądanie sieciowe to Web Push Protocol.

Schemat wysyłania komunikatu push z serwera do usługi push

W tej sekcji przedstawiamy, jak serwer może się identyfikować za pomocą kluczy serwera aplikacji oraz jak jest wysyłany zaszyfrowany ładunek i powiązane z nim dane.

To nie jest ładna strona web push, a ja nie jestem ekspertem w dziedzinie szyfrowania, ale przyjrzyjmy się każdemu z nich, ponieważ łatwo jest dowiedzieć się, co te biblioteki robią za kulisami.

Klucze serwera aplikacji

Gdy subskrybujemy użytkownika, przekazujemy właściwość applicationServerKey. Ten klucz jest przekazywany do usługi push i używany do sprawdzania, czy aplikacja, która zasubskrybowała użytkownika, jest też aplikacją aktywującą wiadomości push.

Gdy uruchamiamy komunikat push, przesyłamy zestaw nagłówków, które umożliwiają usłudze push uwierzytelnianie aplikacji. (definicję tę określa specyfikacja VAPID).

Co to wszystko oznacza i co dokładnie się dzieje? Oto kroki, które trzeba wykonać, aby uwierzytelnić serwer aplikacji:

  1. Serwer aplikacji podpisuje niektóre informacje JSON za pomocą prywatnego klucza aplikacji.
  2. Te podpisane informacje są wysyłane do usługi push jako nagłówek w żądaniu POST.
  3. Usługa push używa zapisanego klucza publicznego otrzymanego od pushManager.subscribe(), aby sprawdzić, czy otrzymane informacje są podpisane kluczem prywatnym powiązanym z kluczem publicznym. Pamiętaj: kluczem publicznym jest applicationServerKey przekazywany do wywołania subskrypcji.
  4. Jeśli podpisane informacje są prawidłowe, usługa push wysyła wiadomość push do użytkownika.

Przykład tego przepływu informacji znajdziesz poniżej. (Zwróć uwagę na legendę w lewym dolnym rogu, aby wskazać klucze publiczne i prywatne).

Ilustracja przedstawiająca sposób używania prywatnego klucza serwera aplikacji podczas wysyłania wiadomości

„Podpisane informacje” dodane do nagłówka w żądaniu to token internetowy JSON.

Token internetowy JSON

Token sieciowy JSON (lub w skrócie JWT) to sposób wysłania wiadomości do osoby trzeciej, dzięki czemu odbiorca może sprawdzić, kto ją wysłał.

Gdy osoba trzecia otrzyma wiadomość, musi uzyskać klucz publiczny nadawcy i użyć go do weryfikacji podpisu tokena JWT. Jeśli podpis jest prawidłowy, token JWT musi być podpisany zgodnym kluczem prywatnym i musi pochodzić od oczekiwanego nadawcy.

Na stronie https://jwt.io/ znajdziesz wiele bibliotek, które mogą wykonać podpisywanie za Ciebie. Zalecamy zrobić to w miarę możliwości. Zobaczmy, jak ręcznie utworzyć podpisany token JWT.

Przelewy z internetu i podpisane tokeny JWT

Podpisany token JWT jest ciągiem znaków, ale może mieć postać 3 ciągów połączonych kropkami.

Ilustracja przedstawiająca ciągi znaków w tokenie internetowym JSON

Pierwszy i drugi łańcuch (informacje JWT i dane JWT) to fragmenty kodu JSON zakodowane w formacie base64, co oznacza, że są dostępne publicznie.

Pierwszy ciąg to informacje o samym tokenie JWT wskazującym, który algorytm został użyty do utworzenia podpisu.

Informacje JWT na potrzeby Web push muszą zawierać te informacje:

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

Drugi ciąg to dane JWT. Te informacje zawierają informacje o nadawcy tokena JWT, do kogo jest przeznaczony i jak długo jest ważny.

W przypadku web push dane będą miały taki format:

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

Wartość aud określa, dla kogo jest przeznaczony token JWT. W przypadku web push lista odbiorców to usługa push, więc ustawiamy dla niej źródło usługi push.

Wartość exp oznacza wygaśnięcie tokena JWT, co uniemożliwia szpiegowcom ponowne użycie tego tokena, jeśli go przechwyci. Data wygaśnięcia jest wyrażona w sekundach i nie może przekraczać 24 godzin.

W środowisku Node.js datę ważności ustawia się za pomocą:

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

Jest to 12 godzin, a nie 24 godziny, aby uniknąć problemów z różnicami w czasie zegara aplikacji wysyłającej i usługi push.

Na koniec wartość sub musi być adresem URL lub adresem e-mail mailto. Dzięki temu, jeśli usługa push potrzebowała kontaktu z nadawcą, mogła znaleźć informacje kontaktowe z tokena JWT. Z tego powodu biblioteka Web-push potrzebowała adresu e-mail.

Podobnie jak informacje JWT dane JWT są kodowane w bezpiecznym adresie URL jako ciąg znaków base64.

Trzeci ciąg, czyli podpis, jest wynikiem przyjęcia 2 pierwszych ciągów (informacji JWT i danych JWT), połączenia ich znakiem kropki, który nazwiemy „token bez podpisu”, i podpisania go.

Proces podpisywania wymaga zaszyfrowania „niepodpisanego tokena” za pomocą standardu ES256. Zgodnie ze specyfikacją JWT ES256 to skrót od „ECDSA używający krzywej P-256 i algorytmu szyfrowania SHA-256”. Korzystając z kryptowalutach internetowych, możesz utworzyć podpis w ten sposób:

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

Usługa push może zweryfikować token JWT za pomocą publicznego klucza serwera aplikacji w celu odszyfrowania podpisu i upewnić się, że odszyfrowany ciąg jest taki sam jak „niepodpisany token” (tzn. dwa pierwsze ciągi w tokenie JWT).

Podpisany token JWT (czyli wszystkie 3 ciągi znaków połączone kropkami) jest wysyłany do usługi webpush jako nagłówek Authorization z dodanym na początku WebPush:

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

Protokół Web Push Protocol określa też, że publiczny klucz serwera aplikacji musi być wysłany w nagłówku Crypto-Key jako ciąg zakodowany w bezpieczny sposób w formacie base64 z dołączonym do niego tagiem p256ecdsa=.

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

Szyfrowanie ładunku

Teraz przyjrzyjmy się, jak wysłać ładunek z wiadomością push, aby aplikacja internetowa mogła uzyskać dostęp do otrzymanych danych.

Osoby, które korzystały z innych usług push często zadają pytanie, dlaczego trzeba szyfrować ładunki push. W przypadku aplikacji natywnych wiadomości push mogą wysyłać dane w postaci zwykłego tekstu.

Jedną z zalet Web push jest to, że wszystkie usługi push używają tego samego interfejsu API (protokołu web push), więc programiści nie muszą się martwić, kto jest usługą push. Możemy wysyłać żądania w odpowiednim formacie i oczekiwać, że zostanie wysłana wiadomość push. Wadą tego rozwiązania jest to, że deweloperzy mogą wysyłać wiadomości do niezaufanej usługi push. Dzięki szyfrowaniu ładunku usługa push nie może odczytać wysyłanych danych. Tylko przeglądarka może odszyfrować informacje. Pozwala to chronić dane użytkownika.

Szyfrowanie ładunku jest zdefiniowane w specyfikacji Message Encryption.

Zanim przejdziemy do konkretnych etapów szyfrowania ładunku wiadomości push, omówimy techniki używane podczas szyfrowania. (wielki napiwek dla Mat Scales za świetny artykuł o szyfrowaniu push).

ECDH i HKDF

W całym procesie szyfrowania używane są zarówno ECDH, jak i HKDF. Zapewniają korzyści związane z szyfrowaniem informacji.

ECDH: wymiana kluczy Diffiego-Hellmana przy użyciu krzywych eliptycznych

Wyobraź sobie, że masz dwie osoby, które chcą udostępnić informacje: Alicję i Roberta. Zarówno Alicja, jak i Robert mają własne klucze publiczne i prywatne. Alicja i Robert udostępniają sobie swoje klucze publiczne.

Przydatną właściwością kluczy wygenerowanych za pomocą ECDH jest to, że Alicja może użyć swojego klucza prywatnego i klucza publicznego Roberta, aby utworzyć wartość obiektu tajnego „X”. To samo może zrobić, używając swojego klucza prywatnego i klucza publicznego Alicji, aby niezależnie utworzyć tę samą wartość „X”. W ten sposób „X” stanie się wspólnym kluczem, a Alicja i Robert muszą udostępnić im tylko swój klucz publiczny. Teraz Robert i Alicja mogą używać „X” do szyfrowania i odszyfrowywania wiadomości między nimi.

ECDH, według mojej najlepszej wiedzy, definiuje właściwości krzywych, które umożliwiają „cechę” tworzenia wspólnego tajnego klucza „X”.

To ogólne objaśnienie ECDH. Jeśli chcesz dowiedzieć się więcej, zachęcam do obejrzenia tego filmu.

Jeśli chodzi o kod, większość języków / platform zawiera biblioteki, które ułatwiają generowanie tych kluczy.

W węźle wykonalibyśmy te działania:

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

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

HKDF: funkcja derywacji klucza oparta na HMAC

Wikipedia zawiera zwięzły opis HKDF:

HKDF to oparta na HMAC funkcja derywacji klucza, która przekształca każdy słaby materiał w mocny kryptograficznie materiał klucza. Można go wykorzystać na przykład do konwertowania udostępnionych przez Diffiego Hellmana udostępnionych obiektów tajnych na materiał klucza nadający się do szyfrowania, sprawdzania integralności lub uwierzytelniania.

Zasadniczo HKDF przyjmuje dane wejściowe, które nie są szczególnie bezpieczne, i zwiększa ich bezpieczeństwo.

Specyfikacja definiująca to szyfrowanie wymaga użycia algorytmu SHA-256 jako naszego algorytmu szyfrowania, a wynikowe klucze dla HKDF w Web push nie powinny być dłuższe niż 256 bitów (32 bajty).

W węźle można to zaimplementować w taki sposób:

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

Wskazówka do artykułu na temat skali matematycznej dotyczącej tego przykładowego kodu.

Ten zakres luźno obejmuje ECDH i HKDF.

ECDH to bezpieczny sposób udostępniania kluczy publicznych i generowania wspólnego obiektu tajnego. HKDF to sposób na przejęcie niezabezpieczonych materiałów i zapewnienie ich bezpieczeństwa.

Będzie ona używana podczas szyfrowania naszego ładunku. Teraz przyjrzyjmy się temu, jakie dane wejściowe są szyfrowane.

Dane wejściowe

Gdy chcemy wysłać użytkownikowi wiadomość push z ładunkiem, potrzebne są 3 informacje wejściowe:

  1. Ładunek.
  2. Obiekt tajny auth z PushSubscription.
  3. Klucz p256dh z PushSubscription.

Widzieliśmy, że wartości auth i p256dh są pobierane z PushSubscription, ale ze względu na subskrypcję potrzebujemy tych wartości:

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

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

Wartość auth powinna być traktowana jako obiekt tajny i nie powinna być udostępniana poza aplikacją.

Klucz p256dh jest kluczem publicznym i czasem nazywanym kluczem publicznym klienta. p256dh to klucz publiczny subskrypcji. Klucz publiczny subskrypcji jest generowany przez przeglądarkę. Przeglądarka zachowa tajny klucz prywatny i wykorzysta go do odszyfrowania ładunku.

Te 3 wartości, auth, p256dh i payload są potrzebne jako dane wejściowe, a wynikiem procesu szyfrowania będzie zaszyfrowany ładunek, wartość ciągu zaburzającego i klucz publiczny używany tylko do szyfrowania danych.

Sól

Ciąg zaburzający musi zawierać 16 bajtów danych losowych. Aby utworzyć sól w NodeJS, wykonaj te czynności:

const salt = crypto.randomBytes(16);

Klucze publiczne / prywatne

Klucze publiczne i prywatne powinny być generowane za pomocą krzywej eliptycznej P-256, co w węźle wykonuje się w ten sposób:

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

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

Będziemy określać je jako „klucze lokalne”. Są używane tylko do szyfrowania i nie mają nic wspólnego z kluczami serwera aplikacji.

Mając ładunek, tajny klucz uwierzytelniania i klucz publiczny subskrypcji jako dane wejściowe, a także nowo wygenerowaną sól i zestaw kluczy lokalnych, możemy od razu zacząć szyfrować.

Udostępniony klucz tajny

Pierwszym krokiem jest utworzenie wspólnego obiektu tajnego przy użyciu klucza publicznego subskrypcji i naszego nowego klucza prywatnego (pamiętaj o wyjaśnieniu ECDH z Alicją i Robertem? Właśnie tak).

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

Służy on w następnym kroku do obliczania Pseudolosowego klucza (PRK).

Pseudolosowy klucz

Pseudo Random Key (PRK) to połączenie klucza uwierzytelniania subskrypcji push i udostępnionego, utworzonego przez nas obiektu tajnego.

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

Pewnie zastanawiasz się, do czego służy ciąg znaków Content-Encoding: auth\0. Krótko mówiąc, nie ma ona wyraźnego celu, chociaż przeglądarki mogą odszyfrować wiadomość przychodzącą i poszukać oczekiwanego kodowania treści. \0 dodaje bajt o wartości 0 na końcu bufora. Jest to możliwe, gdy przeglądarki odszyfrowują wiadomość, która spodziewa się takiej liczby bajtów na potrzeby kodowania treści, potem bajt o wartości 0, a po nim zaszyfrowane dane.

Nasz pseudolosowy klucz uruchamia uwierzytelnianie, wspólny klucz tajny i fragment kodowania danych za pomocą HKDF (czyli zwiększa ich moc kryptograficzną).

kontekst,

„Kontekst” to zbiór bajtów używany do późniejszego obliczania 2 wartości w przeglądarce szyfrowania. Jest to w zasadzie tablica bajtów zawierająca klucz publiczny subskrypcji i lokalny klucz publiczny.

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

Ostatni bufor kontekstu to etykieta, liczba bajtów w kluczu publicznym subskrypcji, po której następuje sam klucz, a następnie liczba bajtów lokalnego klucza publicznego, po której następuje sam klucz.

Dzięki tej wartości kontekstu możemy jej użyć do tworzenia liczby jednorazowej i klucza szyfrowania treści (CEK).

Klucz szyfrowania treści i liczba jednorazowa

Jednorazowa wartość to wartość, która zapobiega powtarzaniu ataku, ponieważ powinna być używana tylko raz.

Klucz szyfrowania treści (CEK) zostanie ostatecznie użyty do szyfrowania ładunku.

Najpierw musimy utworzyć bajty danych dla liczby jednorazowej i CEK. Są to po prostu ciąg kodujący treść, a po nim bufor kontekstu:

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

Informacje są przekazywane przez HKDF, łącząc sól i PRK z nonceInfo i cekInfo:

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

W ten sposób otrzymujemy klucz jednorazowy i klucz szyfrowania treści.

Szyfrowanie

Skoro mamy już klucz szyfrowania treści, możemy zaszyfrować ładunek.

Tworzymy szyfr AES128, używając klucza szyfrowania treści, a liczba jednorazowa to wektor inicjujący.

W Node odbywa się to w ten sposób:

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

Zanim zaszyfrujemy ładunek, musimy określić, jakie dopełnienie ma zostać dodane na początku ładunku. Zdecydowaliśmy się na dodanie dopełnienia, ponieważ zapobiega ono gromadzeniu przez nieupoważnionych osób określenia „typów” wiadomości na podstawie rozmiaru ładunku.

Musisz dodać 2 bajty dopełnienia, aby określić długość dodatkowego dopełnienia.

Jeśli na przykład nie dodasz dopełnienia, otrzymasz 2 bajty z wartością 0, czyli brak dopełnienia, po których będziesz odczytywać ładunek. Jeśli dodasz 5 bajtów dopełnienia, pierwsze 2 bajty będą miały wartość 5, więc konsument odczyta kolejne 5 bajtów, a następnie zacznie odczytywać ładunek.

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

Potem stosujemy dopełnienie i ładunek za pomocą tego szyfrowania.

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

Mamy już zaszyfrowany ładunek. Hura!

Pozostaje już tylko ustalić, jak ten ładunek ma być wysyłany do usługi push.

Zaszyfrowane nagłówki i treść ładunku

Aby wysłać ten zaszyfrowany ładunek do usługi push, musimy zdefiniować kilka różnych nagłówków w żądaniu POST.

Nagłówek szyfrowania

Nagłówek „Szyfrowanie” musi zawierać sól używany do szyfrowania ładunku.

16-bajtowy sól należy zakodować w standardzie base64 i dodać do nagłówka szyfrowania w następujący sposób:

Encryption: salt=[URL Safe Base64 Encoded Salt]

Nagłówek klucza CryptoKey

Zauważyliśmy, że nagłówek Crypto-Key jest używany w sekcji „Klucze serwera aplikacji” do przechowywania publicznego klucza serwera aplikacji.

Ten nagłówek służy też do udostępniania lokalnego klucza publicznego używanego do szyfrowania ładunku.

Wynikowy nagłówek będzie wyglądał tak:

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

Typ treści, długość i nagłówki kodowania

Nagłówek Content-Length to liczba bajtów w zaszyfrowanym ładunku. Nagłówki „Content-Type” i „Content-Encoding” mają stałe wartości. Widać to poniżej.

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

Po ustawieniu nagłówków musimy wysłać zaszyfrowany ładunek jako treść żądania. Zwróć uwagę, że pole Content-Type jest ustawione na application/octet-stream. Dzieje się tak, ponieważ zaszyfrowany ładunek musi być wysłany jako strumień bajtów.

W NodeJS będzie to wyglądało tak:

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

Więcej nagłówków?

Omówiliśmy nagłówki używane w przypadku kluczy JWT lub kluczy serwera aplikacji (tj. sposób identyfikacji aplikacji za pomocą usługi push) oraz nagłówki używane do wysyłania zaszyfrowanego ładunku.

Istnieją dodatkowe nagłówki, które służą do zmiany działania wysyłanych wiadomości przez usługi push. Niektóre z nich są wymagane, a inne opcjonalne.

Nagłówek TTL

Wymagany

TTL (czyli czas życia) to liczba całkowita określająca liczbę sekund, przez które wiadomość push ma pozostawać w usłudze push, zanim zostanie dostarczona. Po wygaśnięciu TTL wiadomość zostanie usunięta z kolejki usługi push i nie zostanie dostarczona.

TTL: [Time to live in seconds]

Jeśli ustawisz TTL o wartości 0, usługa push spróbuje natychmiast dostarczyć wiadomość, ale jeśli urządzenie nie będzie dostępne, wiadomość zostanie natychmiast usunięta z kolejki usługi push.

Technicznie rzecz biorąc, usługa push może zmniejszyć ilość przesyłanych danych (TTL) w razie potrzeby. Możesz się dowiedzieć, czy tak się stało, sprawdzając nagłówek TTL w odpowiedzi z usługi push.

Temat

Opcjonalny

Tematy to ciągi znaków, które umożliwiają zastąpienie oczekujących wiadomości nową wiadomością, jeśli mają one pasujące nazwy tematów.

Jest to przydatne w sytuacjach, gdy gdy urządzenie jest offline, a chcesz, aby użytkownik widział najnowszą wiadomość, tylko gdy jest włączone.

Pilność

Opcjonalny

Pilność wskazuje usłudze push, jak ważna jest wiadomość dla użytkownika. Ta funkcja może być używana przez usługę push, aby oszczędzać baterię urządzenia użytkownika, ponieważ funkcja jest wybudzana w przypadku ważnych komunikatów tylko wtedy, gdy bateria jest bliska rozładowania.

Wartość nagłówka jest zdefiniowana w następujący sposób. Wartością domyślną jest normal.

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

Wszystko razem

Jeśli masz więcej pytań na temat tego, jak to wszystko działa, w organizacji web-push-libs znajdziesz informacje o tym, jak biblioteki uruchamiają wiadomości push.

Gdy masz zaszyfrowany ładunek i powyższe nagłówki, wystarczy, że wyślesz żądanie POST do endpoint w PushSubscription.

Co zrobić z odpowiedzią na to żądanie POST?

Odpowiedź z usługi push

Po wysłaniu żądania do usługi push sprawdź kod stanu odpowiedzi. Dowiesz się z niego, czy żądanie zostało zrealizowane.

Kod stanu Opis
201 Utworzono. Żądanie wysłania wiadomości push zostało odebrane i zaakceptowane.
429 Zbyt wiele żądań. Oznacza to, że serwer aplikacji osiągnął limit liczby żądań z usługą push. Usługa push powinna zawierać nagłówek „Powtórz-po”, aby wskazać, po jakim czasie można wysłać kolejne żądanie.
400 Błędne żądanie. Zwykle oznacza to, że jeden z nagłówków jest nieprawidłowy lub nieprawidłowo sformatowany.
404 Nie znaleziono. Oznacza to, że subskrypcja wygasła i nie można jej użyć. W takim przypadku usuń `PushSubscription` i poczekaj, aż klient ponownie subskrybuje użytkownika.
410 Brak. Subskrypcja nie jest już aktualna i należy ją usunąć z serwera aplikacji. Można to odtworzyć, wywołując funkcję „unsubscribe()” w ramach funkcji „PushSubscription”.
413 Zbyt duży rozmiar ładunku. Minimalny rozmiar ładunku, który musi obsługiwać usługa push, to 4096 bajtów (lub 4 KB).

Co dalej

Laboratoria Code