Protokół Web Push Protocol

Widzieliśmy już, jak biblioteki można wykorzystać do generowania komunikatów push, ale co dokładnie one one oznaczają?

Wysyłają żądania sieciowe, jednocześnie dbając o właściwy format tych żądań. Specyfikacja definiująca to żądanie sieciowe to Web Push Protocol.

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

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

Nie jest to ładna strona web push, a ja nie jestem ekspertem w dziedzinie szyfrowania, ale przyjrzyjmy się każdemu z tych elementów, ponieważ łatwo jest wiedzieć, co te biblioteki robią tak od kuchni.

Klucze serwera aplikacji

Po zasubskrybowaniu kanału użytkownika przekazujemy applicationServerKey. Klucz ten jest przekazywany do usługi push i używany do sprawdzania, czy aplikacja, która zasubskrybowała użytkownika, jest też tą, która aktywuje wiadomości push.

Gdy aktywujemy wiadomość push, otrzymujemy zestaw nagłówków, które pozwalają usłudze push na uwierzytelnienie aplikacji. (definiuje to specyfikacja VAPID).

Co to wszystko tak naprawdę oznacza i co dokładnie się dzieje? Oto kroki, które należy wykonać w celu uwierzytelnienia na serwerze 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: klucz publiczny to 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 sposobu użycia klucza prywatnego serwera aplikacji podczas wysyłania wiadomości

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

Token internetowy JSON

Token sieciowy JSON (w skrócie JWT) to sposób na wysłanie wiadomości do innej firmy, aby odbiorca mógł sprawdzić, kto ją wysłał.

Gdy osoba trzecia otrzyma wiadomość, musi uzyskać klucz publiczny nadawcy i użyć go do zweryfikowania podpisu tokena JWT. Jeśli podpis jest prawidłowy, token JWT musi być podpisany pasującym do niego kluczem prywatnym, więc musi pochodzić od oczekiwanego nadawcy.

Na stronie https://jwt.io/ znajdziesz różne biblioteki, które mogą wykonać podpisywanie. Dla pełnego obrazu zobaczmy, jak ręcznie utworzyć podpisany token JWT.

Komunikaty push i podpisane tokeny JWT

Podpisany token JWT to po prostu ciąg znaków, ale można go traktować jako 3 ciągi połączone kropkami.

Ilustracja przedstawiająca ciągi tekstowe
w tokenie sieciowym JSON

Pierwszy i drugi ciągi (informacje JWT i dane JWT) to fragmenty kodu JSON zakodowane w base64, co oznacza, że są dostępne publicznie.

Pierwszy ciąg zawiera informacje o samym tokenie JWT wskazującym algorytm użyty do utworzenia podpisu.

Informacje JWT dla 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 grupę odbiorców, czyli osobę, dla której jest przeznaczony token JWT. W przypadku push w przeglądarce odbiorców jest usługą push, więc ustawiliśmy dla niej źródło usługi push.

Wartość exp oznacza datę wygaśnięcia tokena JWT. Uniemożliwia to snoopom ponowne użycie tokena JWT, jeśli go przechwyci. Wygaśnięcie ważności jest podawane w sekundach i nie może już wynosić 24 godziny.

W środowisku Node.js datę wygaśnięcia określa się za pomocą:

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

Aby uniknąć problemów z różnicami w zegarze między aplikacją wysyłającą a usługą push, trzeba odczekać 12 godzin, a nie 24 godziny.

Wartość sub musi być adresem URL lub mailto. Dzięki temu, jeśli usługa push, aby skontaktować się z nadawcą, mogła znaleźć informacje kontaktowe z tokena JWT. (Właśnie dlatego biblioteka Web-push potrzebowała adresu e-mail).

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

Trzeci ciąg, czyli podpis, jest wynikiem przyjęcia 2 pierwszych ciągów (informacji JWT i danych JWT) i ich złączenia znakiem kropki, który nazywamy „niepodpisanym tokenem” i podpisania go.

Proces podpisywania wymaga zaszyfrowania „niepodpisanego tokena” za pomocą standardu ES256. Zgodnie ze specyfikacją JWT ES256 jest skrótem od „ECDSA używającego krzywej P-256 i algorytmu szyfrowania SHA-256”. Korzystając z kryptowalut 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” (tj. 2 pierwsze ciągi w tokenie JWT).

Podpisany token JWT (tj. wszystkie 3 ciągi znaków połączone kropkami) jest wysyłany do usługi webpush jako nagłówek Authorization z dołączonym tagiem WebPush, w ten sposób:

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

Zgodnie z protokołem Web Push Protocol publiczny klucz serwera aplikacji musi być wysłany w nagłówku Crypto-Key jako ciąg zakodowany w sposób bezpieczny w adresie URL z dołączonym do niego ciągiem p256ecdsa=.

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

Szyfrowanie ładunku

Teraz przyjrzyjmy się temu, jak wysłać ładunek z komunikatem push, aby aplikacja internetowa, która otrzymała wiadomość push, mogła uzyskać dostęp do odbieranych danych.

Użytkownicy, którzy korzystali z innych usług push często zadają pytania, dlaczego muszą być zaszyfrowane? W przypadku aplikacji natywnych wiadomości push mogą wysyłać dane jako zwykły tekst.

Jedną z zalet Web push jest to, że wszystkie usługi push korzystają z 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 we właściwym formacie i oczekiwać, że zostanie wysłany komunikat push. Wadą takiego 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. Chroni to dane użytkownika.

Szyfrowanie ładunku jest zdefiniowane w specyfikacji Message Encryption.

Zanim przyjrzymy się poszczególnym krokom szyfrowania ładunku wiadomości push, omówimy kilka technik używanych podczas szyfrowania. (wielki napiwek dla Mat Scales za świetny artykuł o szyfrowaniu push).

ECDH i HKDF

W procesie szyfrowania używane są zarówno ECDH, jak i HKDF, co zapewnia korzyści w zakresie szyfrowania informacji.

ECDH: wymiana kluczy według krzywej eliptycznej Diffiego-Hellmana

Wyobraź sobie, że masz 2 osoby, które chcą udostępniać 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 do utworzenia wartości obiektu tajnego „X”. To samo może zrobić Robert, 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 tajnym , a Alicja i Robert muszą udostępnić im tylko swój klucz publiczny. Teraz Robert i Alicja mogą używać „X”, aby szyfrować i odszyfrowywać wiadomości między nimi.

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

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

W przypadku kodu: większość języków / platform udostępnia biblioteki, które ułatwiają generowanie tych kluczy.

W węźle wykonaj te czynności:

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

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

HKDF: funkcja derywacji klucza HMAC

Wikipedia zawiera zwięzły opis hasła HKDF:

HKDF to funkcja derywacji klucza HMAC, która przekształca dowolny słaby materiał klucza w silny kryptograficznie materiał klucza. Można dzięki niemu na przykład przekonwertować udostępnione tajne klucze Diffie Hellmana na materiał klucza, który nadaje 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 SHA-256 jako 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 ten 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 dotycząca kapelusza do artykułu Mat Scale dotyczącego tego przykładowego kodu.

Ten zakres luźno obejmuje ECDH i HKDF.

ECDH to bezpieczny sposób udostępniania kluczy publicznych i generowania wspólnych kluczy tajnych. 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, potrzebujemy 3 rodzajów danych:

  1. Sam ładunek.
  2. Obiekt tajny auth z interfejsu PushSubscription.
  3. Klucz p256dh z PushSubscription.

Widzieliśmy wartości auth i p256dh pobierane z PushSubscription, ale w związku z 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 jest udostępniana poza aplikacją.

Klucz p256dh jest kluczem publicznym i czasem nazywanym kluczem publicznym klienta. Będziemy tu określać p256dh jako klucz publiczny subskrypcji. Klucz publiczny subskrypcji jest generowany przez przeglądarkę. Przeglądarka zachowa klucz prywatny jako tajny klucz i użyje 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ść zaburzająca i klucz publiczny używany tylko do szyfrowania danych.

Sól

Ciąg zaburzający musi mieć 16 bajtów losowych danych. W NodeJS utworzymy sól w ten sposób:

const salt = crypto.randomBytes(16);

Klucze publiczne / prywatne

Klucze publiczne i prywatne powinny być generowane z wykorzystaniem krzywej eliptycznej P-256, co robimy w węźle w taki sposób:

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

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

Będziemy je nazywać „kluczami lokalnymi”. Są używane tylko do szyfrowania i nie mają nic wspólnego z kluczami serwera aplikacji.

Mając dane wejściowe, klucz tajny uwierzytelniania i klucz publiczny subskrypcji oraz nowo wygenerowany sól i zestaw kluczy lokalnych, możemy zacząć szyfrować dane.

Udostępniony klucz tajny

Pierwszym krokiem jest utworzenie wspólnego obiektu tajnego przy użyciu klucza publicznego subskrypcji i naszego nowego klucza prywatnego (pamiętasz wyjaśnienie ECDH z Alicją i Robertem? Właśnie w ten sposób).

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

Zostanie on użyty w następnym kroku do obliczenia Pseudolosowego klucza (PRK).

Pseudolosowy klucz

Pseudo Random Key (PRK) to połączenie tajnego klucza uwierzytelniania subskrypcji push i utworzonego przed chwilą udostępnionego klucza tajnego.

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

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

Nasz pseudolosowy klucz uruchamia uwierzytelnianie, wspólny klucz tajny i fragment kodu kodowania przez HKDF (czyli zwiększa jego kryptografię).

Kontekst

„Kontekst” to zbiór bajtów, które są używane do późniejszego obliczania 2 wartości w przeglądarce szyfrowania. Jest to 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, następnie liczba bajtów lokalnego klucza publicznego, a po nim sam klucz.

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

Klucz szyfrowania treści i liczba jednorazowa

Element jednorazowy to wartość, która zapobiega ponownemu atakowaniu, ponieważ powinna być używana tylko raz.

Klucz szyfrowania treści (CEK) to klucz, który będzie ostatecznie używany do szyfrowania naszego ładunku.

Najpierw musimy utworzyć bajty danych dla liczby jednorazowej i CEK, czyli ciągu do kodowania treści, a po nim bufora kontekstu, który właśnie obliczyliśmy:

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 te są przesyłane 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 dostajemy klucz jednorazowy i klucz szyfrowania treści.

Przeprowadź 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 węźle 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. Dopełnianie tych pól zapobiega 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ść każdego dodatkowego dopełnienia.

Jeśli na przykład nie dodasz dopełnienia, uzyskasz 2 bajty z wartością 0, czyli nie będzie dopełnienia. Po tych 2 bajtach 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 i 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);

Następnie używamy dopełnienia i ładunku przez ten mechanizm 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 teraz nasz zaszyfrowany ładunek. Hura!

Pozostaje już tylko określenie sposobu wysyłania tego ładunku do usługi push.

Nagłówki i treść zaszyfrowanego ł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żywaną do szyfrowania ładunku.

16-bajtowy sól należy zakodować w formacie base64 i dodać do nagłówka szyfrowania w ten 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 umieszczenia klucza publicznego serwera aplikacji.

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

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” to wartości stałe. 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 Content-Type ma wartość application/octet-stream. Wynika to z faktu, że zaszyfrowany ładunek musi zostać wysłany jako strumień bajtów.

W NodeJS zrobimy to w ten sposób:

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 tokenach JWT i kluczach serwera aplikacji (czyli sposób identyfikowania aplikacji za pomocą usługi push) oraz nagłówków służących do wysyłania zaszyfrowanego ładunku.

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

Nagłówek TTL

Wymagane

TTL (inaczej czas życia) to liczba całkowita określająca, przez ile sekund wiadomość push ma być aktywna 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 na wartość 0, usługa push spróbuje dostarczyć wiadomość natychmiast, ale jeśli urządzenie nie będzie dostępne, wiadomość zostanie natychmiast usunięta z kolejki usługi push.

Z technicznego punktu widzenia usługa push może w razie potrzeby zmniejszyć TTL przesyłanej wiadomości. Aby sprawdzić, czy tak się stało, przejrzyj nagłówek TTL w odpowiedzi z usługi push.

Temat

Opcjonalny

Tematy to ciągi tekstowe, które można wykorzystać do zastąpienia oczekujących wiadomości nową wiadomością, jeśli mają pasujące nazwy tematów.

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

Pilność

Opcjonalny

Pilność wskazuje usłudze push, jak ważna jest wiadomość dla użytkownika. Może ona być używana przez usługę push, aby oszczędzać baterię urządzenia użytkownika, ponieważ wybudza się 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 w jednym miejscu

Jeśli masz więcej pytań na temat tego, jak to działa, w każdej chwili możesz sprawdzić, jak biblioteki aktywują wiadomości push w organizacji web-push-libs.

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

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

Odpowiedź z usługi push

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

Kod stanu Opis
201 Utworzono. Prośba o wysłanie wiadomości push została odebrana i zaakceptowana.
429 Zbyt wiele żądań. Oznacza to, że serwer aplikacji osiągnął limit liczby żądań w usłudze push. Usługa push powinna zawierać nagłówek „Retry-After”, który wskazuje, 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 wykupi subskrypcję użytkownika.
410 Brak. Subskrypcja nie jest już aktualna i należy ją usunąć z serwera aplikacji. Można go odtworzyć, wywołując funkcję „unsubscribe()” w 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 kodu