Kita telah melihat cara library dapat digunakan untuk memicu pesan push, tetapi apa sebenarnya yang dilakukan library ini?
Nah, mereka membuat permintaan jaringan sambil memastikan permintaan tersebut dalam format yang tepat. Spesifikasi yang menentukan permintaan jaringan ini adalah Web Push Protocol.
Bagian ini menguraikan cara server mengidentifikasi dirinya dengan kunci server aplikasi dan cara payload terenkripsi serta data terkait dikirim.
Ini bukan sisi yang bagus dari push web dan saya bukan ahli enkripsi, tetapi mari kita lihat setiap bagian karena akan berguna untuk mengetahui apa yang dilakukan library ini di balik layar.
Kunci server aplikasi
Saat mendaftarkan pengguna, kita akan meneruskan applicationServerKey. Kunci ini
diteruskan ke layanan push dan digunakan untuk memeriksa bahwa aplikasi yang mendaftarkan
pengguna juga merupakan aplikasi yang memicu pesan push.
Saat kami memicu pesan push, ada serangkaian header yang kami kirim yang memungkinkan layanan push mengautentikasi aplikasi. (Ini ditentukan oleh spesifikasi VAPID.)
Apa arti semua ini dan apa yang sebenarnya terjadi? Berikut adalah langkah-langkah yang dilakukan untuk autentikasi server aplikasi:
- Server aplikasi menandatangani beberapa informasi JSON dengan kunci aplikasi pribadi.
- Informasi bertanda tangan ini dikirim ke layanan push sebagai header dalam permintaan POST.
- Layanan push menggunakan kunci publik tersimpan yang diterimanya dari
pushManager.subscribe()untuk memeriksa apakah informasi yang diterima ditandatangani oleh kunci pribadi yang terkait dengan kunci publik. Ingat: Kunci publik adalahapplicationServerKeyyang diteruskan ke panggilan subscribe. - Jika informasi yang ditandatangani valid, layanan push akan mengirimkan pesan push kepada pengguna.
Contoh alur informasi ini ada di bawah. (Perhatikan legenda di kiri bawah untuk menunjukkan kunci publik dan pribadi.)
"Informasi yang ditandatangani" yang ditambahkan ke header dalam permintaan adalah Token Web JSON.
Token web JSON
Token web JSON (atau JWT) adalah cara untuk mengirim pesan ke pihak ketiga sehingga penerima dapat memvalidasi siapa yang mengirimkannya.
Saat menerima pesan, pihak ketiga harus mendapatkan kunci publik pengirim dan menggunakannya untuk memvalidasi tanda tangan JWT. Jika tanda tangan valid, JWT pasti telah ditandatangani dengan kunci pribadi yang cocok sehingga pasti berasal dari pengirim yang diharapkan.
Ada banyak library di jwt.io/ yang dapat melakukan penandatanganan untuk Anda dan sebaiknya Anda melakukannya jika memungkinkan. Untuk kelengkapan, mari kita lihat cara membuat JWT bertanda tangan secara manual.
Notifikasi push web dan JWT yang ditandatangani
JWT yang ditandatangani hanyalah string, meskipun dapat dianggap sebagai tiga string yang digabungkan dengan titik.
String pertama dan kedua (Info JWT dan data JWT) adalah bagian dari JSON yang telah dienkode dengan base64, yang berarti dapat dibaca oleh publik.
String pertama adalah informasi tentang JWT itu sendiri, yang menunjukkan algoritma mana yang digunakan untuk membuat tanda tangan.
Info JWT untuk push web harus berisi informasi berikut:
{
"typ": "JWT",
"alg": "ES256"
}
String kedua adalah Data JWT. Bagian ini memberikan informasi tentang pengirim JWT, siapa yang dituju, dan berapa lama JWT tersebut valid.
Untuk push web, data akan memiliki format ini:
{
"aud": "https://some-push-service.org",
"exp": "1469618703",
"sub": "mailto:example@web-push-book.org"
}
Nilai aud adalah "audiens", yaitu untuk siapa JWT tersebut. Untuk push web, audiensnya adalah layanan push, jadi kita menyetelnya ke origin layanan push.
Nilai exp adalah masa berlaku JWT, yang mencegah pengintai dapat menggunakan kembali JWT jika mereka mencegatnya. Masa berlaku adalah stempel waktu dalam
detik dan tidak boleh lebih dari 24 jam.
Di Node.js, masa berlaku ditetapkan menggunakan:
Math.floor(Date.now() / 1000) + 12 * 60 * 60;
Waktunya adalah 12 jam, bukan 24 jam, untuk menghindari masalah perbedaan waktu antara aplikasi pengirim dan layanan push.
Terakhir, nilai sub harus berupa URL atau alamat email mailto.
Hal ini dilakukan agar jika layanan push perlu menghubungi pengirim, layanan tersebut dapat menemukan informasi kontak dari JWT. (Inilah alasan library web-push memerlukan alamat email).
Sama seperti Info JWT, Data JWT dienkode sebagai string base64 yang aman bagi URL.
String ketiga, tanda tangan, adalah hasil dari pengambilan dua string pertama (Info JWT dan Data JWT), menggabungkannya dengan karakter titik, yang akan kita sebut sebagai "token yang tidak ditandatangani", dan menandatanganinya.
Proses penandatanganan memerlukan enkripsi "token yang tidak ditandatangani" menggunakan ES256. Menurut spesifikasi JWT, ES256 adalah singkatan dari "ECDSA menggunakan kurva P-256 dan algoritma hash SHA-256". Dengan menggunakan web crypto, 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 untuk mendekripsi tanda tangan dan memastikan string yang didekripsi sama dengan "token yang tidak ditandatangani" (yaitu dua string pertama dalam JWT).
JWT yang ditandatangani (yaitu ketiga string yang digabungkan dengan titik), dikirim ke layanan push web sebagai header Authorization dengan WebPush yang ditambahkan di depannya, seperti berikut:
Authorization: 'WebPush [JWT Info].[JWT Data].[Signature]';
Web Push Protocol juga menyatakan bahwa kunci server aplikasi publik harus
dikirim di header Crypto-Key sebagai string berenkode base64 yang aman untuk URL dengan
p256ecdsa= yang ditambahkan di depannya.
Crypto-Key: p256ecdsa=[URL Safe Base64 Public Application Server Key]
Enkripsi Payload
Selanjutnya, mari kita lihat cara mengirim payload dengan pesan push sehingga saat aplikasi web kita menerima pesan push, aplikasi tersebut dapat mengakses data yang diterimanya.
Pertanyaan umum yang muncul dari siapa pun yang telah menggunakan layanan push lainnya adalah mengapa payload push web perlu dienkripsi? Dengan aplikasi native, pesan push dapat mengirim data sebagai teks biasa.
Salah satu keunggulan push web adalah karena semua layanan push menggunakan API yang sama (protokol push web), developer tidak perlu memedulikan siapa layanan push tersebut. Kita dapat membuat permintaan dalam format yang tepat dan mengharapkan pesan push dikirim. Kekurangannya adalah developer dapat mengirim pesan ke layanan push yang tidak tepercaya. Dengan mengenkripsi payload, layanan push tidak dapat membaca data yang dikirim. Hanya browser yang dapat mendekripsi informasi tersebut. Tindakan ini akan melindungi data pengguna.
Enkripsi payload ditentukan dalam spesifikasi Enkripsi Pesan.
Sebelum melihat langkah-langkah spesifik untuk mengenkripsi payload pesan push, kita harus membahas beberapa teknik yang akan digunakan selama proses enkripsi. (Terima kasih banyak kepada Mat Scales atas artikelnya yang sangat bagus tentang enkripsi push.)
ECDH dan HKDF
ECDH dan HKDF digunakan di seluruh proses enkripsi dan menawarkan manfaat untuk tujuan mengenkripsi 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 masing-masing. Alice dan Bob saling membagikan kunci publik mereka.
Properti berguna dari kunci yang dihasilkan dengan ECDH adalah Alice dapat menggunakan kunci pribadinya dan kunci publik Bob untuk membuat nilai rahasia 'X'. Bob dapat melakukan hal yang sama, dengan menggunakan kunci pribadinya dan kunci publik Alice untuk membuat nilai 'X' yang sama secara independen. Hal ini menjadikan 'X' sebagai rahasia bersama dan Alice serta Bob hanya perlu membagikan kunci publik mereka. Sekarang Bob dan Alice dapat menggunakan 'X' untuk mengenkripsi dan mendekripsi pesan di antara mereka.
ECDH, sepengetahuan saya, menentukan properti kurva yang memungkinkan "fitur" ini untuk membuat rahasia bersama 'X'.
Ini adalah penjelasan tingkat tinggi tentang ECDH; jika Anda ingin mempelajari lebih lanjut, sebaiknya tonton video ringkasan ECDH yang lebih mendetail.
Dari segi kode, sebagian besar bahasa / platform dilengkapi dengan library untuk mempermudah pembuatan kunci ini.
Di node, kita akan melakukan hal berikut:
const keyCurve = crypto.createECDH('prime256v1');
keyCurve.generateKeys();
const publicKey = keyCurve.getPublicKey();
const privateKey = keyCurve.getPrivateKey();
HKDF: Fungsi turunan kunci berbasis HMAC
Wikipedia memiliki deskripsi singkat tentang HKDF:
HKDF adalah fungsi turunan kunci berbasis HMAC yang mengubah materi kunci yang lemah menjadi materi kunci yang kuat secara kriptografis. Contohnya, dapat digunakan untuk mengonversi rahasia bersama yang dipertukarkan Diffie Hellman menjadi materi kunci yang cocok untuk digunakan dalam enkripsi, pemeriksaan integritas, atau autentikasi.
Pada dasarnya, HKDF akan mengambil input yang tidak terlalu 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).
Di 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);
}
Terima kasih kepada artikel Mat Scale untuk kode contoh ini.
Bagian ini secara umum mencakup ECDH dan HKDF.
ECDH adalah cara aman untuk membagikan kunci publik dan membuat rahasia bersama. HKDF adalah cara untuk mengambil materi yang tidak aman dan membuatnya aman.
Nilai ini akan digunakan selama enkripsi payload kita. Selanjutnya, mari kita lihat apa yang kita ambil sebagai input dan cara mengenkripsinya.
Input
Saat ingin mengirim pesan push ke pengguna dengan payload, ada tiga input yang kita butuhkan:
- Payload itu sendiri.
- Secret
authdariPushSubscription. - Kunci
p256dhdariPushSubscription.
Kami telah melihat nilai auth dan p256dh diambil dari PushSubscription, tetapi sebagai pengingat cepat, mengingat langganan, kami memerlukan 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, yang terkadang disebut sebagai kunci publik klien. Di sini
kita akan menyebut p256dh sebagai kunci publik langganan. Kunci publik langganan dibuat
oleh browser. Browser akan merahasiakan kunci pribadi dan menggunakannya untuk mendekripsi payload.
Ketiga nilai ini, auth, p256dh, dan payload, diperlukan sebagai input dan hasil dari proses
enkripsi akan berupa payload terenkripsi, nilai salt, dan kunci publik yang digunakan hanya untuk
mengenkripsi data.
Salt
Salt harus berupa data acak 16 byte. Di NodeJS, kita akan melakukan hal berikut untuk membuat salt:
const salt = crypto.randomBytes(16);
Kunci Publik / Pribadi
Kunci publik dan pribadi harus dibuat menggunakan kurva elips 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();
Kita akan menyebut kunci ini sebagai "kunci lokal". Kunci ini digunakan hanya untuk enkripsi dan tidak ada hubungannya dengan kunci server aplikasi.
Dengan payload, secret auth, dan kunci publik langganan sebagai input serta dengan salt dan set kunci lokal yang baru dibuat, kita siap melakukan beberapa enkripsi.
Rahasia bersama
Langkah pertama adalah membuat rahasia bersama menggunakan kunci publik langganan dan kunci pribadi baru kami (ingat penjelasan ECDH dengan Alice dan Bob? Semudah itu).
const sharedSecret = localKeysCurve.computeSecret(
subscription.keys.p256dh,
'base64',
);
Nilai ini digunakan pada langkah berikutnya untuk menghitung Kunci Pseudo-Random (PRK).
Kunci pseudo-random
Kunci Pseudo Random (PRK) adalah kombinasi dari rahasia otorisasi langganan push, 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, tidak memiliki tujuan yang jelas, meskipun browser dapat
mendekripsi pesan masuk dan mencari encoding konten yang diharapkan.
\0 menambahkan byte dengan nilai 0 ke akhir Buffer. Hal ini diharapkan oleh browser yang mendekripsi pesan yang akan mengharapkan begitu banyak byte untuk encoding konten, diikuti dengan byte dengan nilai 0, diikuti dengan data terenkripsi.
Kunci Pseudo Random kami hanya menjalankan info otorisasi, rahasia bersama, dan info encoding melalui HKDF (yaitu, membuatnya lebih kuat secara kriptografis).
Konteks
"Konteks" adalah sekumpulan byte yang digunakan untuk menghitung dua nilai nanti di browser enkripsi. Pada dasarnya, ini 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,
]);
Buffer konteks akhir adalah label, jumlah byte di kunci publik langganan, diikuti dengan kunci itu sendiri, lalu jumlah byte kunci publik lokal, diikuti dengan 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 serangan replay karena hanya boleh digunakan satu kali.
Kunci enkripsi konten (CEK) adalah kunci yang pada akhirnya akan digunakan untuk mengenkripsi payload kita.
Pertama, kita perlu membuat byte data untuk nonce dan CEK, yang hanya berupa string encoding konten yang diikuti dengan 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);
Tindakan ini memberi kita nonce dan kunci enkripsi konten.
Lakukan enkripsi
Setelah memiliki kunci enkripsi konten, kita dapat mengenkripsi payload.
Kami membuat cipher AES128 menggunakan kunci enkripsi konten sebagai kunci dan nonce sebagai vektor inisialisasi.
Di Node, hal ini dilakukan seperti berikut:
const cipher = crypto.createCipheriv(
'id-aes128-GCM',
contentEncryptionKey,
nonce,
);
Sebelum mengenkripsi payload, kita perlu menentukan jumlah padding yang ingin ditambahkan ke bagian depan payload. Alasan kami ingin menambahkan padding adalah untuk mencegah risiko penyadap dapat menentukan "jenis" pesan berdasarkan ukuran payload.
Anda harus menambahkan dua byte padding untuk menunjukkan panjang padding tambahan.
Misalnya, jika Anda 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 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 menjalankan padding dan payload melalui sandi 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()]);
Sekarang kita memiliki payload terenkripsi. Asyik!
Yang tersisa adalah menentukan cara payload ini dikirim ke layanan push.
Header & isi payload terenkripsi
Untuk mengirim payload terenkripsi ini ke layanan push, kita perlu menentukan beberapa header yang berbeda dalam permintaan POST.
Header enkripsi
Header 'Encryption' harus berisi salt yang digunakan untuk mengenkripsi payload.
Salt 16 byte harus dienkode dengan aman untuk 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 bagian 'Kunci Server Aplikasi'
untuk memuat kunci server aplikasi publik.
Header ini juga digunakan untuk membagikan kunci publik lokal yang digunakan untuk mengenkripsi payload.
Header 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]
Header jenis konten, panjang & encoding
Header Content-Length adalah jumlah byte dalam payload
terenkripsi. Header 'Content-Type' dan 'Content-Encoding' adalah nilai tetap.
Hal ini ditunjukkan di bawah.
Content-Length: [Number of Bytes in Encrypted Payload]
Content-Type: 'application/octet-stream'
Content-Encoding: 'aesgcm'
Dengan header ini yang ditetapkan, kita perlu mengirimkan payload terenkripsi sebagai isi
permintaan kita. Perhatikan bahwa Content-Type ditetapkan ke
application/octet-stream. Hal ini karena payload terenkripsi harus
dikirim sebagai aliran byte.
Di NodeJS, kita akan melakukannya seperti ini:
const pushRequest = https.request(httpsOptions, function(pushResponse) {
pushRequest.write(encryptedPayload);
pushRequest.end();
Header lainnya?
Kita telah membahas header yang digunakan untuk JWT / Kunci Server Aplikasi (yaitu cara mengidentifikasi aplikasi dengan layanan push) dan kita telah membahas header yang digunakan untuk mengirim payload terenkripsi.
Ada header tambahan yang digunakan layanan push untuk mengubah perilaku pesan yang dikirim. Beberapa header ini wajib ada, sedangkan yang lain bersifat opsional.
Header TTL
Wajib
TTL (atau time to live) adalah bilangan bulat yang menentukan jumlah detik
yang Anda inginkan agar pesan push tetap aktif di layanan push sebelum
dikirimkan. Jika masa berlaku TTL berakhir, pesan akan dihapus dari antrean layanan push dan tidak akan dikirim.
TTL: [Time to live in seconds]
Jika Anda menyetel TTL ke nol, layanan push akan mencoba mengirimkan
pesan dengan segera, tetapi jika perangkat tidak dapat dijangkau, pesan Anda
akan langsung dihapus dari antrean layanan push.
Secara teknis, layanan push dapat mengurangi TTL pesan push jika
diinginkan. Anda dapat mengetahui apakah hal ini terjadi dengan memeriksa header TTL dalam respons dari layanan push.
Topik
Opsional
Topik adalah string yang dapat digunakan untuk mengganti pesan yang tertunda dengan pesan baru jika memiliki nama topik yang cocok.
Hal ini berguna dalam skenario saat beberapa pesan dikirim saat perangkat offline, dan Anda hanya ingin pengguna melihat pesan terbaru saat perangkat diaktifkan.
Urgensi
Opsional
Urgensi menunjukkan kepada layanan push seberapa penting pesan bagi pengguna. Hal ini dapat digunakan oleh layanan push untuk membantu menghemat masa pakai baterai perangkat pengguna dengan hanya mengaktifkan perangkat untuk pesan penting saat baterai lemah.
Nilai header ditentukan seperti yang ditunjukkan di bawah. Nilai defaultnya adalah normal.
Urgency: [very-low | low | normal | high]
Semuanya bersama-sama
Jika ada pertanyaan lebih lanjut tentang cara kerja semua ini, Anda dapat melihat cara library memicu pesan push di org web-push-libs.
Setelah memiliki payload terenkripsi dan header di atas, Anda hanya perlu membuat permintaan POST
ke endpoint dalam PushSubscription.
Jadi, apa yang kita lakukan dengan respons terhadap permintaan POST ini?
Respons dari layanan push
Setelah membuat permintaan ke layanan push, Anda harus memeriksa kode status respons karena kode tersebut akan memberi tahu Anda apakah permintaan berhasil atau tidak.
| Kode Status | Deskripsi |
|---|---|
| 201 | Dibuat. Permintaan untuk mengirim pesan push telah diterima dan disetujui. |
| 429 | Terlalu banyak permintaan. Artinya, server aplikasi Anda telah mencapai batas jumlah permintaan dengan layanan push. Layanan push harus menyertakan header 'Retry-After' untuk menunjukkan berapa lama sebelum permintaan lain dapat dilakukan. |
| 400 | Permintaan tidak valid. Error ini umumnya berarti salah satu header Anda tidak valid atau diformat dengan tidak benar. |
| 404 | Tidak Ditemukan. Hal ini menunjukkan bahwa langganan telah berakhir dan tidak dapat digunakan. Dalam hal ini, Anda harus menghapus `PushSubscription` dan menunggu klien untuk mendaftarkan ulang pengguna. |
| 410 | Sudah tidak ada. Langganan tidak lagi valid dan harus dihapus dari server aplikasi. Hal ini dapat direproduksi dengan memanggil `unsubscribe()` di `PushSubscription`. |
| 413 | Ukuran payload terlalu besar. Payload ukuran minimum yang harus didukung oleh layanan push adalah 4096 byte (atau 4 kb). |
Anda juga dapat membaca standar Web Push (RFC8030) untuk mengetahui informasi selengkapnya tentang kode status HTTP.
Langkah berikutnya
- Ringkasan Notifikasi Push Web
- Cara Kerja Push
- Berlangganan Pengguna
- UX Izin
- Mengirim Pesan dengan Library Push Web
- Protokol Web Push
- Menangani Peristiwa Push
- Menampilkan Notifikasi
- Perilaku Notifikasi
- Pola Notifikasi Umum
- FAQ Notifikasi Push
- Masalah Umum dan Melaporkan Bug