{i>Web Push Protocol

Kita telah melihat bagaimana {i>library<i} dapat digunakan untuk memicu pesan {i>push<i}, tetapi apa yang dilakukan perpustakaan ini?

Nah, mereka membuat permintaan jaringan sambil memastikan permintaan tersebut format yang tepat. Spesifikasi yang mendefinisikan permintaan jaringan ini adalah Protokol Push Web.

Diagram pengiriman pesan push dari server Anda ke push
layanan

Bagian ini menjelaskan cara server mengidentifikasi dirinya sendiri dengan aplikasi kunci server dan bagaimana muatan terenkripsi dan data terkait dikirim.

Ini bukan sisi yang baik dari {i>web push<i} dan saya tidak ahli dalam enkripsi, tapi mari kita lihat setiap bagian karena sangat berguna untuk mengetahui apa yang dilakukan perpustakaan ini di balik layar.

Kunci server aplikasi

Saat membuat pengguna berlangganan, kita meneruskan applicationServerKey. Kunci ini diteruskan ke layanan push dan digunakan untuk memeriksa bahwa aplikasi yang berlangganan pengguna juga merupakan aplikasi yang memicu pesan {i>push<i}.

Ketika kita memicu pesan {i>push<i}, ada serangkaian {i>header<i} yang kita kirim memungkinkan layanan push untuk mengotentikasi aplikasi. (Hal ini ditentukan dengan spesifikasi VAPID.)

Apa arti semua ini sebenarnya dan apa yang sebenarnya terjadi? Nah, ini adalah langkah-langkah yang diambil untuk autentikasi server aplikasi:

  1. Server aplikasi menandatangani beberapa informasi JSON dengan kunci aplikasi pribadinya.
  2. Informasi bertanda tangan ini dikirim ke layanan push sebagai header dalam permintaan POST.
  3. Layanan push menggunakan kunci publik yang disimpan yang diterimanya dari pushManager.subscribe() untuk memeriksa bahwa informasi yang diterima ditandatangani oleh kunci pribadi yang terkait dengan kunci publik. Ingat: Kunci publik bersifat applicationServerKey yang diteruskan ke panggilan berlangganan.
  4. Jika informasi yang ditandatangani valid, layanan push akan mengirimkan push kepada pengguna.

Contoh aliran informasi ini adalah sebagai berikut. (Perhatikan legenda di kiri bawah untuk menunjukkan kunci publik dan pribadi.)

Ilustrasi tentang cara kunci server aplikasi pribadi digunakan saat mengirim
pesan

"Informasi bertanda tangan" yang ditambahkan ke header dalam permintaan adalah Token Web JSON.

Token web JSON

Token web JSON (atau disingkat JWT) adalah cara untuk mengirim pesan ke pihak ketiga sehingga penerima dapat memvalidasi siapa yang mengirimnya.

Saat pihak ketiga menerima pesan, mereka harus mendapatkan pengirim kunci publik dan menggunakannya untuk memvalidasi tanda tangan JWT. Jika valid maka JWT harus ditandatangani dengan kunci pribadi sehingga harus dikirim dari pengirim yang seharusnya.

Ada sejumlah perpustakaan di https://jwt.io/ yang dapat melakukan penandatanganan untuk Anda dan sebaiknya Anda melakukannya di mana Anda bisa. Untuk kelengkapan, mari kita lihat cara membuat JWT yang ditandatangani secara manual.

JWT yang ditandatangani dan push web

JWT yang ditandatangani hanyalah sebuah {i>string<i}, meskipun dapat dianggap sebagai tiga {i>string<i} dengan titik.

Ilustrasi string di Web JSON
{i>Token<i}

{i>String<i} pertama dan kedua (Info JWT dan data JWT) adalah potongan dari JSON yang telah dienkode dengan format base64, artinya dapat dibaca oleh publik.

String pertama adalah informasi tentang JWT itu sendiri, yang menunjukkan algoritma yang mana digunakan untuk membuat tanda tangan.

Info JWT untuk web push harus berisi informasi berikut:

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

{i>String<i} kedua adalah Data JWT. Ini memberikan informasi tentang pengirim JWT, yang sesuai dengan yang dituju dan berapa lama itu valid.

Untuk web push, data akan memiliki format ini:

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

Nilai aud adalah "audience", yaitu untuk siapa JWT. Untuk web, tekan tombol adalah layanan push, jadi kita tetapkan ke asal push layanan.

Nilai exp merupakan akhir masa berlaku JWT, ini mencegah pengintai dapat menggunakan kembali JWT jika mereka mencegatnya. Kedaluwarsa adalah stempel waktu pada detik dan tidak boleh lebih dari 24 jam.

Di Node.js, masa berlaku ditetapkan menggunakan:

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

12 jam, bukan 24 jam, untuk menghindari masalah apa pun dengan perbedaan jam antara aplikasi pengirim dan layanan push.

Terakhir, nilai sub harus berupa URL atau alamat email mailto. Hal ini agar jika layanan {i>push<i} perlu menghubungi pengirim, layanan itu dapat menemukan informasi kontak dari JWT. (Inilah mengapa pustaka web-push membutuhkan alamat email Anda).

Sama seperti Info JWT, Data JWT dienkode sebagai base64 yang aman untuk URL {i>string<i}.

{i>String<i} ketiga, tanda tangan, adalah hasil dari pengambilan dua {i>string<i} pertama (Info JWT dan Data JWT), menggabungkannya dengan karakter titik, yang akan kita memanggil "{i>unsigned token<i}", dan menandatanganinya.

Proses penandatanganan mengharuskan enkripsi "token tidak ditandatangani" ES256. Menurut JWT, spec, ES256 adalah singkatan dari "ECDSA menggunakan kurva P-256 dan algoritma hash SHA-256". Dengan menggunakan kripto web, Anda dapat membuat tanda tangan seperti berikut:

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

Layanan push dapat memvalidasi JWT menggunakan kunci server aplikasi publik membongkar enkripsi tanda tangan dan memastikan string yang didekripsi sama sebagai "token tidak bertanda tangan" (yaitu dua string pertama di JWT).

JWT yang ditandatangani (yaitu ketiga string yang digabungkan dengan titik), dikirim ke web push layanan sebagai header Authorization dengan WebPush ditambahkan di awal, seperti ini:

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

{i>Web Push Protocol<i} juga menyatakan bahwa kunci server aplikasi publik harus dikirim di header Crypto-Key sebagai string berenkode base64 yang aman untuk URL dengan p256ecdsa= menambahkannya.

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

Enkripsi Muatan

Selanjutnya, mari kita lihat bagaimana kita bisa mengirim {i>payload<i} dengan pesan {i>push<i} sehingga ketika aplikasi web kita menerima pesan {i>push<i}, maka dapat mengakses data yang diterimanya.

Pertanyaan umum yang muncul dari semua yang pernah menggunakan layanan push lainnya adalah mengapa web push {i>payload<i} perlu dienkripsi? Dengan aplikasi native, pesan push dapat mengirim data sebagai teks biasa.

Salah satu keunggulan web push adalah karena semua layanan push menggunakan API yang sama (protokol web push), pengembang tidak perlu peduli dengan layanan push tersebut. Kita dapat membuat permintaan dalam format yang tepat dan mengharapkan pesan push yang akan dikirim. Kelemahan dari ini adalah pengembang tidak bisa mungkin mengirim pesan ke layanan {i>push<i} yang tidak tepercaya. Menurut mengenkripsi payload, layanan {i>push<i} tidak dapat membaca data yang dikirim. Hanya browser yang dapat mendekripsi informasi. Ini melindungi layanan otomatis dan data skalabel.

Enkripsi payload didefinisikan dalam Enkripsi Pesan spesifikasi.

Sebelum membahas langkah-langkah spesifik untuk mengenkripsi payload pesan push, kita harus membahas beberapa teknik yang akan digunakan selama enkripsi {i>checkout<i}. (Tipe topi besar untuk Mat Scales atas artikelnya yang luar biasa tentang push encryption.)

ECDH dan HKDF

ECDH dan HKDF digunakan di seluruh proses enkripsi dan menawarkan manfaat bagi tujuan enkripsi informasi.

ECDH: Pertukaran kunci Elliptic Curve Diffie-Hellman

Bayangkan Anda memiliki dua orang yang ingin berbagi informasi, Alice dan Bob. Alice dan Bob memiliki kunci publik dan pribadi mereka sendiri. Alice dan Bob saling berbagi kunci publik mereka.

Properti kunci yang berguna yang dihasilkan dengan ECDH adalah Alice dapat menggunakannya kunci pribadi dan kunci publik Bob untuk membuat nilai rahasia 'X'. Yang bisa dilakukan Bobi hal yang sama, mengambil kunci pribadinya dan kunci publik Alice untuk secara independen menciptakan nilai 'X' yang sama. Ini menghasilkan 'X' rahasia bersama sedangkan Alice dan Bob hanya perlu berbagi kunci publik mereka. Sekarang Bob dan Alice bisa menggunakan 'X' untuk mengenkripsi dan membongkar enkripsi pesan di antara keduanya.

ECDH, sepanjang pengetahuan saya, menentukan sifat-sifat kurva yang memungkinkan "fitur" ini pembuatan 'X' rahasia bersama.

Ini adalah penjelasan umum tentang ECDH. Jika Anda ingin mempelajari lebih lanjut, sebaiknya tonton video ini.

Dalam hal kode; sebagian besar bahasa / platform dilengkapi dengan {i>library<i} untuk membuatnya proses pembuatan kunci tersebut.

Dalam node, kita akan melakukan hal berikut:

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

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

HKDF: Fungsi derivasi kunci berbasis HMAC

Wikipedia memiliki deskripsi singkat tentang HKDF:

HKDF adalah fungsi derivasi kunci berbasis HMAC yang mengubah setiap kunci yang lemah menjadi materi kunci yang kuat secara kriptografis. Dapat digunakan, untuk misalnya, untuk mengonversi Diffie Hellman bertukar rahasia bersama menjadi informasi penting cocok untuk digunakan dalam enkripsi, pemeriksaan integritas, atau otentikasi.

Pada dasarnya, HKDF akan menerima input yang tidak aman dan membuatnya lebih aman.

Spesifikasi yang menentukan enkripsi ini memerlukan penggunaan SHA-256 sebagai algoritma hash kami dan kunci yang dihasilkan untuk HKDF di web push tidak boleh lebih dari 256 bit (32 byte).

Dalam node, hal ini dapat diterapkan seperti berikut:

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

Tips topi ke artikel Mat Scale untuk kode contoh ini.

Video ini secara longgar membahas ECDH dan HKDF.

ECDH adalah cara yang aman untuk berbagi kunci publik dan menghasilkan rahasia bersama. HKDF adalah cara untuk mengambil materi yang tidak aman dan membuatnya aman.

Kunci ini akan digunakan selama enkripsi payload. Selanjutnya mari kita lihat apa yang kita ambil sebagai input teks dan bagaimana hal itu dienkripsi.

Input

Saat kita ingin mengirim pesan push ke pengguna dengan payload, ada tiga input yang kita perlukan:

  1. Payload itu sendiri.
  2. Rahasia auth dari PushSubscription.
  3. Kunci p256dh dari PushSubscription.

Kita telah melihat nilai auth dan p256dh yang diambil dari PushSubscription, tetapi untuk pengingat cepat, mengingat langganan, kita memerlukan nilai-nilai ini:

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

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

Nilai auth harus diperlakukan sebagai rahasia dan tidak dibagikan di luar aplikasi Anda.

Kunci p256dh adalah kunci publik, terkadang disebut sebagai kunci publik klien. Di sini, p256dh adalah kunci publik langganan. Kunci publik langganan dibuat oleh browser. Browser akan menjaga kerahasiaan kunci pribadi itu dan menggunakannya untuk membuka enkripsi payload.

Ketiga nilai ini, auth, p256dh, dan payload diperlukan sebagai input dan hasil dari enkripsi akan menjadi {i>payload<i} yang terenkripsi, nilai {i>salt<i} dan kunci publik yang digunakan hanya untuk mengenkripsi data.

Garam

Salt harus berukuran 16 byte data acak. Di NodeJS, kita melakukan hal berikut untuk membuat salt:

const salt = crypto.randomBytes(16);

Kunci Publik / Pribadi

Kunci publik dan pribadi harus dihasilkan menggunakan kurva eliptis P-256, yang akan kita lakukan di Node seperti berikut:

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

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

Kami akan menyebut kunci ini sebagai "kunci lokal". Kunci ini hanya digunakan untuk enkripsi dan memiliki tidak ada yang berhubungan dengan kunci server aplikasi.

Dengan payload, rahasia autentikasi, dan kunci publik langganan sebagai input, {i>salt<i} dan set kunci lokal, kita siap untuk melakukan beberapa enkripsi.

Rahasia bersama

Langkah pertama adalah membuat rahasia bersama menggunakan kunci publik langganan dan kunci pribadi (ingat penjelasan ECDH bersama Alice dan Bob? Mudah bukan).

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

Hal ini digunakan pada langkah berikutnya untuk menghitung Kunci Acak Pseudo (PRK).

Kunci acak semu

Kunci Acak Pseudo (PRK) adalah kombinasi autentikasi langganan push rahasia, dan rahasia bersama yang baru saja kita buat.

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

Anda mungkin bertanya-tanya untuk apa string Content-Encoding: auth\0. Singkatnya, itu tidak memiliki tujuan yang jelas, meskipun {i>browser<i} dapat mendekripsi pesan masuk dan mencari encoding konten yang diharapkan. \0 menambahkan byte dengan nilai 0 ke akhir Buffer. Ini adalah diharapkan oleh browser yang membongkar enkripsi pesan, yang akan mengharapkan begitu banyak {i>byte<i} untuk encoding konten, diikuti oleh byte dengan nilai 0, data yang terenkripsi.

Kunci Acak Pseudo kita hanya menjalankan auth, rahasia bersama, dan informasi encoding melalui HKDF (yaitu menjadikannya lebih kuat secara kriptografis).

Konteks

"Konteks" adalah seperangkat byte yang digunakan untuk menghitung dua nilai nanti dalam enkripsi browser. Pada dasarnya, {i>array<i} adalah array byte yang berisi kunci publik langganan dan kunci publik lokal.

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

Buffering konteks terakhir adalah label, jumlah byte dalam kunci publik langganan, diikuti oleh kunci itu sendiri, kemudian jumlah byte kunci publik lokal, diikuti oleh kunci itu sendiri.

Dengan nilai konteks ini, kita dapat menggunakannya dalam pembuatan nonce dan kunci enkripsi konten (CEK).

Kunci enkripsi konten dan nonce

Nonce adalah nilai yang mencegah replay serangan karena hanya boleh digunakan sekali.

Kunci enkripsi konten (CEK) adalah kunci yang pada akhirnya akan digunakan untuk mengenkripsi payload.

Pertama, kita perlu membuat byte data untuk nonce dan CEK, yang string encoding diikuti oleh buffer konteks yang baru saja kita hitung:

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

Informasi ini dijalankan melalui HKDF yang menggabungkan salt dan PRK dengan nonceInfo dan 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);

Ini akan memberi kita nonce dan kunci enkripsi konten.

Melakukan enkripsi

Setelah memiliki kunci enkripsi konten, kita dapat mengenkripsi payload.

Kami membuat penyandian AES128 menggunakan kunci enkripsi konten, sebagai kunci, sedangkan nonce adalah vektor inisialisasi.

Di Node, hal ini dilakukan seperti berikut:

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

Sebelum mengenkripsi payload, kita perlu menentukan seberapa banyak padding yang kita inginkan untuk ditambahkan di depan payload. Alasan kita ingin menambahkan padding adalah bahwa hal itu mencegah risiko penyadap mampu menentukan "jenis" pesan berdasarkan ukuran payload.

Anda harus menambahkan dua byte padding untuk menunjukkan panjang padding tambahan.

Misalnya, jika tidak menambahkan padding, Anda akan memiliki dua byte dengan nilai 0, yaitu tidak ada padding. Setelah dua byte ini, Anda akan membaca payload. Jika Anda menambahkan padding 5 byte, dua byte pertama akan memiliki nilai 5, sehingga konsumen kemudian akan membaca lima byte tambahan lalu mulai membaca payload.

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

Kemudian, kita jalankan {i> padding<i} dan payload melalui penyandian ini.

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

Kita sekarang memiliki payload terenkripsi. Asyik!

Yang tersisa hanyalah menentukan bagaimana payload ini dikirim ke layanan push.

Header payload yang dienkripsi & badan

Untuk mengirim {i>payload<i} terenkripsi ini ke layanan {i> push<i}, kita perlu mendefinisikan beberapa {i>header<i} yang berbeda dalam permintaan POST kita.

Header enkripsi

'Enkripsi' header harus berisi salt yang digunakan untuk mengenkripsi payload.

Salt 16 byte harus dienkode dengan aman ke URL base64 dan ditambahkan ke header Enkripsi, seperti berikut:

Encryption: salt=[URL Safe Base64 Encoded Salt]

Header Crypto-Key

Kita melihat bahwa header Crypto-Key digunakan di bawah 'Kunci Server Aplikasi' yang berisi kunci server aplikasi publik.

{i>Header<i} ini juga digunakan untuk membagikan kunci publik lokal yang digunakan untuk mengenkripsi payload.

{i>Header<i} yang dihasilkan akan terlihat seperti ini:

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

Jenis, durasi &konten header encoding

Header Content-Length adalah jumlah byte dalam payload. 'Jenis-Konten' dan 'Content-Encoding' {i>header <i}adalah nilai tetap. Hal ini ditunjukkan di bawah ini.

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

Setelah {i>header <i}ini disetel, kita perlu mengirimkan {i>payload<i} terenkripsi sebagai isi permintaan kami. Perhatikan bahwa Content-Type disetel ke application/octet-stream. Ini karena {i>payload<i} yang terenkripsi harus dikirim sebagai aliran byte.

Di NodeJS, kita akan melakukan ini seperti berikut:

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

Header lainnya?

Kita telah membahas {i>header<i} yang digunakan untuk JWT / Kunci Server Aplikasi (yaitu cara mengidentifikasi aplikasi dengan layanan push) dan kita telah membahas header yang digunakan untuk mengirim permintaan payload.

Ada {i>header<i} tambahan yang digunakan layanan push untuk mengubah perilaku mengirim pesan. Beberapa {i>header<i} ini wajib ada, sementara yang lain bersifat opsional.

Header TTL

Wajib

TTL (atau waktu aktif) adalah bilangan bulat yang menentukan jumlah detik Anda ingin pesan push Anda aktif di layanan {i>push<i} sebelum yang dihasilkan. Jika TTL kedaluwarsa, pesan akan dihapus dari antrean layanan {i>push<i} dan itu tidak akan dikirimkan.

TTL: [Time to live in seconds]

Jika Anda menetapkan TTL ke nol, layanan push akan mencoba mengirimkan segera, tetapi jika perangkat tidak dapat dijangkau, pesan Anda akan segera dihapus dari antrean layanan push.

Secara teknis layanan push dapat mengurangi TTL pesan push jika kita inginkan. Anda dapat mengetahui apakah ini terjadi dengan memeriksa header TTL di respons dari layanan push.

Topik

Opsional

Topik adalah string yang dapat digunakan untuk mengganti pesan yang tertunda dengan pesan baru jika mereka memiliki nama topik yang cocok.

Hal ini berguna dalam skenario ketika beberapa pesan dikirim saat perangkat sedang offline, dan Anda benar-benar hanya ingin pengguna melihat yang terbaru saat perangkat diaktifkan.

Urgensi

Opsional

Urgensi menunjukkan ke layanan {i>push<i} seberapa penting sebuah pesan bagi pengguna. Ini dapat digunakan oleh layanan push untuk membantu menghemat masa pakai baterai perangkat pengguna dengan hanya bangun untuk menerima pesan penting saat baterai lemah.

Nilai header ditentukan seperti yang ditunjukkan di bawah ini. Nilai defaultnya adalah normal.

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

Semuanya

Jika Anda memiliki pertanyaan lebih lanjut tentang cara kerja semua ini, Anda selalu bisa melihat bagaimana library terpicu mengirim pesan di web-push-libs org.

Setelah Anda memiliki {i>payload<i} yang dienkripsi, dan {i>header<i} di atas, Anda hanya perlu membuat permintaan POST ke endpoint di PushSubscription.

Jadi apa yang kita lakukan dengan respons atas permintaan POST ini?

Respons dari layanan push

Setelah membuat permintaan ke layanan push, Anda perlu memeriksa kode status respons yang akan memberi tahu Anda apakah permintaan berhasil atau tidak.

Kode Status Deskripsi
201 Dibuat. Permintaan untuk mengirim pesan push telah diterima dan diterima.
429 Terlalu banyak permintaan. Artinya server aplikasi Anda telah mencapai kecepatan batasan dengan layanan push. Layanan push harus menyertakan perintah 'Retry-After' {i>header<i} untuk menunjukkan waktu sebelum permintaan lain dapat dibuat.
400 Permintaan tidak valid. Ini biasanya berarti salah satu header Anda tidak valid atau tidak diformat dengan benar.
404 Tidak Ditemukan. Ini merupakan indikasi bahwa langganan sudah tidak berlaku dan tidak dapat digunakan. Dalam hal ini, Anda harus menghapus `PushSubscription` dan menunggu klien untuk berlangganan pengguna kembali.
410 Pergi. Langganan ini tidak lagi valid dan harus dihapus dari server aplikasi. Ini dapat direproduksi dengan memanggil `unsubscribe()` pada `PushSubscription`.
413 Ukuran payload terlalu besar. Ukuran minimum payload yang harus dimiliki layanan push dukungan adalah 4096 byte (atau 4 kb).

Langkah berikutnya

Lab kode