Web Push Protokolü

Matt Gaunt

Bir kitaplığın push mesajları tetiklemek için nasıl kullanılabileceğini gördük. Peki bu kitaplıklar tam olarak ne yapıyor?

Bu tür istekler doğru biçimde olduğundan emin olarak ağ istekleri gönderiyorlar. Bu ağ isteğini tanımlayan spesifikasyon Web Push Protokolü'dür.

Sunucunuzdan bir push hizmetine push mesajı gönderme şeması

Bu bölümde, sunucunun uygulama sunucusu anahtarlarıyla kendisini nasıl tanımlayabileceği ve şifrelenmiş yük ile ilişkili verilerin nasıl gönderildiği açıklanmaktadır.

Bu, web push'in hoş bir yönü değil ve şifreleme konusunda uzman değilim. Ancak bu kitaplıkların arka planda neler yaptığını bilmek yararlı olduğu için her bir parçayı inceleyelim.

Uygulama sunucusu anahtarları

Bir kullanıcıyı abone ettiğimizde bir applicationServerKey iletiyoruz. Bu anahtar, push hizmetine iletilir ve kullanıcıyı abone eden uygulamanın aynı zamanda push mesajlarını tetikleyen uygulama olup olmadığını kontrol etmek için kullanılır.

Bir push mesajını tetiklediğimizde, push hizmetinin uygulamanın kimliğini doğrulamasına olanak tanıyan bir dizi üstbilgi göndeririz. (Bu, VAPID spesifikasyonu tarafından tanımlanır.)

Peki bu tam olarak ne anlama geliyor ve ne oluyor? Uygulama sunucusu kimlik doğrulaması için uygulanan adımlar şunlardır:

  1. Uygulama sunucusu, bazı JSON bilgilerini özel uygulama anahtarıyla imzalar.
  2. Bu imzalı bilgiler, bir POST isteğinde başlık olarak push hizmetine gönderilir.
  3. Push hizmeti, alınan bilgilerin ortak anahtarla ilgili özel anahtarla imzalandığını kontrol etmek için pushManager.subscribe()'ten aldığı depolanan ortak anahtarı kullanır. Hatırlatma: Ortak anahtar, abone olma çağrısına iletilen applicationServerKey değeridir.
  4. İmzalı bilgiler geçerliyse push hizmeti, push mesajını kullanıcıya gönderir.

Bu bilgi akışına örnek olarak aşağıdaki görseli inceleyebilirsiniz. (Genel ve özel anahtarları gösteren sol alttaki açıklamaya dikkat edin.)

Mesaj gönderirken özel uygulama sunucusu anahtarının nasıl kullanıldığını gösteren görsel

İstekte bir başlığa eklenen "imzalı bilgiler" JSON Web Token'dur.

JSON Web jetonu

JSON web jetonu (veya kısaca JWT), bir iletiyi üçüncü tarafa göndermenin, alıcı tarafından göndereni doğrulayabileceği bir yoludur.

Bir üçüncü taraf bir ileti aldığında, gönderenin ortak anahtarını alması ve JWT'nin imzasını doğrulamak için bu anahtarı kullanması gerekir. İmza geçerliyse JWT, eşleşen özel anahtarla imzalanmış olmalıdır. Bu nedenle, beklenen gönderenden gelmiş olmalıdır.

https://jwt.io/ adresinde, imzalama işlemini sizin için gerçekleştirebilecek çok sayıda kitaplık vardır. Mümkün olduğunda bu kitaplıkları kullanmanızı öneririz. Tamlık açısından, imzalı bir JWT'nin manuel olarak nasıl oluşturulacağına bakalım.

Web push ve imzalı JWT'ler

İmzalı JWT yalnızca bir dizedir ancak noktalarla birleştirilmiş üç dize olarak düşünülebilir.

JSON Web Jetonu'ndaki dizelerin resmi

İlk ve ikinci dizeler (JWT bilgileri ve JWT verileri), base64 kodlanmış JSON parçalarıdır. Yani herkes tarafından okunabilir.

İlk dize, JWT ile ilgili bilgilerdir ve imza oluşturmak için hangi algoritmanın kullanıldığını belirtir.

Web push için JWT bilgileri aşağıdaki bilgileri içermelidir:

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

İkinci dize, JWT verileridir. Bu, JWT'nin göndereni, kim için gönderildiği ve ne kadar süreyle geçerli olduğu hakkında bilgi sağlar.

Web push için veriler şu biçimde olur:

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

aud değeri, "kitle" yani JWT'nin kim için olduğudur. Web push'te kitle, push hizmeti olduğundan kitleyi push hizmetinin kaynağına ayarlarız.

exp değeri, JWT'nin geçerlilik süresini belirtir. Bu, bilgi hırsızlarının JWT'yi ele geçirirse yeniden kullanamamasını sağlar. Süre sonu, saniye cinsinden bir zaman damgası olup 24 saatten uzun olmamalıdır.

Node.js'de geçerlilik bitiş tarihi şu şekilde ayarlanır:

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

Gönderen uygulama ile push hizmeti arasındaki saat farklılıklarından kaynaklanabilecek sorunları önlemek için bu süre 24 saat yerine 12 saattir.

Son olarak, sub değerinin bir URL veya mailto e-posta adresi olması gerekir. Bu, bir push hizmetinin gönderene ulaşması gerektiğinde JWT'den iletişim bilgilerini bulabilmesi içindir. (Bu nedenle web push kitaplığının bir e-posta adresine ihtiyacı vardı).

JWT Bilgileri gibi JWT Verileri de URL için güvenli base64 dizesi olarak kodlanır.

İmza olan üçüncü dize, ilk iki dizeyi ("JWT Bilgileri" ve "JWT Verileri") "imzasız jeton" olarak adlandıracağımız bir nokta karakteriyle birleştirip imzalamanın sonucudur.

İmzalama işlemi, "imzasız jetonun" ES256 kullanılarak şifrelenmesini gerektirir. JWT spesifikasyonuna göre ES256, "P-256 eğrisini ve SHA-256 karma algoritmasını kullanan ECDSA"nın kısaltmasıdır. Web şifrelemesini kullanarak imzayı aşağıdaki gibi oluşturabilirsiniz:

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

Bir push hizmeti, imzanın şifresini çözmek ve şifresi çözülmüş dizenin "imzasız jeton"la (yani JWT'deki ilk iki dize) aynı olduğundan emin olmak için genel uygulama sunucusu anahtarını kullanarak JWT'yi doğrulayabilir.

İmzalı JWT (yani üç dizenin de noktayla birleştirilmesi), web push hizmetine WebPush başlığı eklenmiş Authorization başlığı olarak gönderilir. Örneğin:

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

Web Push Protokolü, ortak uygulama sunucusu anahtarının Crypto-Key başlığında, p256ecdsa= öne eklenmiş bir URL güvenli base64 kodlu dize olarak gönderilmesi gerektiğini de belirtir.

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

Yük şifrelemesi

Ardından, web uygulamamız bir push mesajı aldığında aldığı verilere erişebilmesi için push mesajıyla nasıl bir yük gönderebileceğimize bakalım.

Diğer push hizmetlerini kullananların sıklıkla sorduğu bir soru, web push yükü neden şifrelenmelidir? Yerleşik uygulamalarda push mesajları verileri düz metin olarak gönderebilir.

Web push'in avantajlarından biri, tüm push hizmetlerinin aynı API'yi (web push protokolü) kullanması nedeniyle geliştiricilerin push hizmetinin kim olduğuna dikkat etmemesidir. Doğru biçimde bir istek gönderebilir ve bir push mesajının gönderilmesini bekleyebiliriz. Bunun dezavantajı, geliştiricilerin güvenilir olmayan bir push hizmetine mesaj gönderebilmesidir. Ağırlığı şifreleyen bir itme hizmeti, gönderilen verileri okuyamaz. Bilgilerin şifresini yalnızca tarayıcı çözebilir. Bu sayede kullanıcının verileri korunur.

Yükün şifrelemesi, Mesaj Şifreleme spesifikasyonunda tanımlanır.

Bir push mesajı yükü şifrelemeyle ilgili belirli adımlara bakmadan önce, şifreleme işlemi sırasında kullanılacak bazı teknikleri ele almamız gerekir. (Mat Scales'in push şifrelemesiyle ilgili mükemmel makalesi için kendisine çok teşekkür ederiz.)

ECDH ve HKDF

Hem ECDH hem de HKDF, şifreleme işlemi boyunca kullanılır ve bilgileri şifreleme amacıyla avantajlar sunar.

ECDH: Eliptik Eğri Diffie-Hellman anahtar değişimi

Bilgi paylaşmak isteyen iki kişi olduğunu varsayalım. Bu kişiler Ayşe ve Ali. Hem Ayşe hem de Ali'nin kendi herkese açık ve özel anahtarları vardır. Ayşe ve Bora, ortak anahtarlarını birbirleriyle paylaşır.

ECDH ile oluşturulan anahtarların yararlı özelliği, Alice'in gizli "X" değerini oluşturmak için kendi özel anahtarını ve Bob'un ortak anahtarını kullanabilmesidir. Barış da aynısını yapabilir. Özel anahtarını ve Ayşe'nin ortak anahtarını kullanarak bağımsız olarak aynı "X" değerini oluşturabilir. Bu, "X"i paylaşılan bir sır yapar ve Ayla ile Bora'nın yalnızca ortak anahtarlarını paylaşması gerekir. Artık Ali ve Ayşe, aralarındaki mesajları şifrelemek ve şifresini çözmek için "X"i kullanabilir.

Bildiğim kadarıyla ECDH, ortak bir gizli "X" oluşturma "özelliğine" olanak tanıyan eğrilerin özelliklerini tanımlar.

Bu, ECDH'nin üst düzey bir açıklamasıdır. Daha fazla bilgi edinmek isterseniz bu videoya göz atmanızı öneririz.

Kod açısından, çoğu dil / platform bu anahtarları oluşturmayı kolaylaştırmak için kitaplıklarla birlikte gelir.

Nod'da şunları yaparız:

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

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

HKDF: HMAC tabanlı anahtar türetme işlevi

Wikipedia'da HKDF ile ilgili kısa bir açıklama yer alır:

HKDF, zayıf anahtar materyallerini kriptografik olarak güçlü anahtar materyallerine dönüştüren HMAC tabanlı bir anahtar türetme işlevidir. Örneğin, Diffie-Hellman ile paylaşılan gizli bilgileri şifreleme, bütünlük kontrolü veya kimlik doğrulamada kullanılmaya uygun anahtar materyaline dönüştürmek için kullanılabilir.

Temel olarak HKDF, özellikle güvenli olmayan girişleri alıp daha güvenli hale getirir.

Bu şifrelemeyi tanımlayan spesifikasyon, karma oluşturma algoritmamız olarak SHA-256'nın kullanılmasını gerektirir ve web push'inde HKDF için elde edilen anahtarlar en fazla 256 bit (32 bayt) uzunluğunda olmalıdır.

Node'da bu işlem aşağıdaki gibi uygulanabilir:

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

Bu örnek kod için Mat Scale'ın makalesine göz atın.

Bu, ECDH ve HKDF'yi kapsar.

ECDH, herkese açık anahtarları paylaşmanın ve paylaşılan bir gizli anahtar oluşturmanın güvenli bir yoludur. HKDF, güvenli olmayan materyalleri güvenli hale getirmenin bir yoludur.

Bu, yükümüzün şifrelenmesi sırasında kullanılır. Ardından, giriş olarak neleri aldığımıza ve bunların nasıl şifrelendiğine bakalım.

Girişler

Bir kullanıcıya yük içeren bir push mesajı göndermek istediğimizde üç girişe ihtiyacımız vardır:

  1. Yükün kendisi.
  2. PushSubscription'daki auth gizli anahtarı.
  3. PushSubscription'daki p256dh anahtarı.

auth ve p256dh değerlerinin bir PushSubscription kaynağından alındığını gördük. Abonelik için şu değerlere ihtiyacımız olduğunu hatırlatmak isteriz:

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

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

auth değeri gizli olarak değerlendirilmeli ve uygulamanız dışında paylaşılmamalıdır.

p256dh anahtarı bir ortak anahtardır. Buna bazen istemci ortak anahtarı da denir. Burada p256dh, abonelik için ortak anahtar olarak adlandırılır. Abonelik ortak anahtarı tarayıcı tarafından oluşturulur. Tarayıcı, özel anahtarı gizli tutar ve yükü şifresini çözmek için kullanır.

Giriş olarak auth, p256dh ve payload değerlerinin kullanılması gerekir. Şifreleme işleminin sonucu, şifrelenmiş yük, bir tuz değeri ve yalnızca verileri şifrelemek için kullanılan bir ortak anahtar olur.

Tuz

Tuz, 16 baytlık rastgele veri olmalıdır. NodeJS'de tuz oluşturmak için aşağıdakileri yaparız:

const salt = crypto.randomBytes(16);

Herkese açık / gizli anahtarlar

Ortak ve özel anahtarlar, P-256 eliptik eğrisi kullanılarak oluşturulmalıdır. Bunu Node'da aşağıdaki gibi yaparız:

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

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

Bu anahtarlara "yerel anahtarlar" diyeceğiz. Bu anahtarlar yalnızca şifreleme için kullanılır ve uygulama sunucusu anahtarlarıyla hiçbir ilgisi yoktur.

Gönderi, kimlik doğrulama gizlisi ve abonelik ortak anahtarı girişleri, yeni oluşturulmuş bir tuz ve yerel anahtar grubu ile şifreleme yapmaya hazırız.

Paylaşılan gizli anahtar

İlk adım, abonelik ortak anahtarını ve yeni özel anahtarımızı kullanarak paylaşılan bir gizli anahtar oluşturmaktır (Alice ve Bob ile ilgili ECDH açıklamasını hatırlıyor musunuz? Bu kadar.)

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

Bu değer, sonraki adımda sözde rastgele anahtarı (PRK) hesaplamak için kullanılır.

Sanal rastgele anahtar

Sanal rastgele anahtar (PRK), push aboneliğinin kimlik doğrulama gizli anahtarının ve az önce oluşturduğumuz paylaşılan gizli anahtarın birleşimidir.

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

Content-Encoding: auth\0 dizesinin ne işe yaradığını merak ediyor olabilirsiniz. Kısacası, net bir amacı yoktur ancak tarayıcılar gelen bir mesajın şifresini çözebilir ve beklenen içerik kodlamasını arayabilir. \0, tamponun sonuna 0 değerine sahip bir bayt ekler. Bu, mesajın şifresini çözen tarayıcılar tarafından beklenir. Bu tarayıcılar, içerik kodlaması için bu kadar bayt, ardından 0 değerine sahip bir bayt ve ardından şifrelenmiş veriler bekler.

Sanal Rastgele Anahtarımız, kimlik doğrulama, paylaşılan gizli bilgi ve kodlama bilgilerinin bir kısmını HKDF üzerinden çalıştırır (yani şifreleme açısından daha güçlü hale getirir).

Bağlam

"Bağlam", daha sonra şifreleme tarayıcısında iki değeri hesaplamak için kullanılan bir bayt kümesidir. Aslında abonelik ortak anahtarını ve yerel ortak anahtarı içeren bir bayt dizisidir.

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

Son bağlam arabelleği bir etikettir. Abonelik ortak anahtarındaki bayt sayısı, ardından anahtar, ardından yerel ortak anahtardaki bayt sayısı ve ardından anahtar gelir.

Bu bağlam değerini, tek kullanımlık sayı ve içerik şifreleme anahtarı (İTŞ) oluşturmak için kullanabiliriz.

İçerik şifreleme anahtarı ve tek seferlik sayı

Nonce, yalnızca bir kez kullanılması gerektiği için yeniden oynatma saldırılarını önleyen bir değerdir.

İçerik şifreleme anahtarı (CEK), yükümüzü şifrelemek için nihai olarak kullanılacak anahtardır.

Öncelikle, nonce ve CEK için veri baytlarını oluşturmamız gerekir. Bu, basitçe bir içerik kodlama dizesi ve ardından hesapladığımız bağlam arabelleğinin birleşimidir:

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

Bu bilgiler, salt ve PRK'yı nonceInfo ve cekInfo ile birleştiren HKDF üzerinden çalıştırılır:

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

Bu işlemle tek seferlik sayı ve içerik şifreleme anahtarımızı elde ederiz.

Şifrelemeyi gerçekleştirin

İçerik şifreleme anahtarımıza sahip olduğumuza göre yükü şifreleyebiliriz.

Anahtar olarak içerik şifreleme anahtarını, tek kullanımlık şifreleme sayısı olarak da bir başlatma vektörünü kullanarak bir AES128 şifresi oluştururuz.

Node'da bu işlem şu şekilde yapılır:

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

Yükümüzü şifrelemeden önce, yükün önüne ne kadar dolgu eklemek istediğimizi tanımlamamız gerekir. Doldurma eklemek istememizin nedeni, dinleyicilerin yükü boyutuna göre iletilerin "türlerini" belirleyebilmesi riskini önlemesidir.

Ek dolgunun uzunluğunu belirtmek için iki bayt dolgu eklemeniz gerekir.

Örneğin, dolgu eklemediyseniz 0 değerine sahip iki bayt olur.Yani dolgu yoktur. Bu iki bayttan sonra yükü okursunuz. 5 bayt dolgu eklediyseniz ilk iki baytın değeri 5 olur. Bu nedenle, tüketici ek beş bayt okuduktan sonra yükü okumaya başlar.

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

Ardından, dolgu ve yükümüzü bu şifreleme üzerinden çalıştırırız.

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

Artık şifrelenmiş yükümüze sahibiz. Yaşasın!

Geriye kalan tek şey, bu yükün push hizmetine nasıl gönderileceğini belirlemektir.

Şifrelenmiş yük üstbilgileri ve gövdesi

Bu şifrelenmiş yükün push hizmetine gönderilmesi için POST isteğimizde birkaç farklı üst bilgi tanımlamamız gerekir.

Şifreleme üstbilgisi

"Encryption" (Şifreleme) üstbilgisinde, yükün şifrelenmesi için kullanılan salt bulunmalıdır.

16 baytlık tuz, base64 URL güvenli kodlu olmalı ve şifreleme başlığına aşağıdaki gibi eklenmelidir:

Encryption: salt=[URL Safe Base64 Encoded Salt]

Crypto-Key üstbilgisi

Crypto-Key başlığının, herkese açık uygulama sunucusu anahtarını içermek için "Uygulama Sunucusu Anahtarları" bölümünde kullanıldığını gördük.

Bu başlık, yükü şifrelemek için kullanılan yerel ortak anahtarı paylaşmak için de kullanılır.

Elde edilen başlık şu şekilde görünür:

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

İçerik türü, uzunluk ve kodlama üstbilgileri

Content-Length başlığı, şifrelenmiş yükteki bayt sayısıdır. "Content-Type" ve "Content-Encoding" üstbilgileri sabit değerlerdir. Bu durum aşağıdaki şekilde gösterilmiştir.

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

Bu üstbilgiler ayarlandıktan sonra, şifrelenmiş yükün isteğimizin gövdesi olarak gönderilmesi gerekir. Content-Type değerinin application/octet-stream olarak ayarlandığını unutmayın. Bunun nedeni, şifrelenmiş yükün bir bayt akışı olarak gönderilmesi gerektiğidir.

NodeJS'de bunu şu şekilde yaparız:

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

Daha fazla üstbilgi mi?

JWT / uygulama sunucusu anahtarları için kullanılan üstbilgileri (ör. uygulamayı push hizmetiyle tanımlama) ve şifrelenmiş bir yükü göndermek için kullanılan üstbilgileri ele aldık.

Push hizmetlerinin, gönderilen iletilerin davranışını değiştirmek için kullandığı ek üstbilgiler vardır. Bu üstbilgilerden bazıları zorunlu, bazıları ise isteğe bağlıdır.

TTL üstbilgisi

Zorunlu

TTL (veya geçerlilik süresi), push mesajınızın yayınlanmadan önce push hizmetinde yayınlanmasını istediğiniz saniye sayısını belirten bir tam sayıdır. TTL süresi dolduktan sonra mesaj, push hizmeti kuyruğundan kaldırılır ve teslim edilmez.

TTL: [Time to live in seconds]

TTL değerini sıfır olarak ayarlarsanız push hizmeti mesajı hemen yayınlamaya çalışır. Ancak cihaza ulaşılamazsa mesajınız push hizmeti kuyruğundan hemen çıkarılır.

Teknik olarak bir push hizmeti, isterse push mesajının TTL değerini düşürebilir. Bunun olup olmadığını, push hizmetinden gelen yanıttaki TTL üst bilgisini inceleyerek anlayabilirsiniz.

Konu

İsteğe bağlı

Konu, bekleyen iletilerin konu adları eşleşiyorsa yeni bir iletiyle değiştirilmesi için kullanılabilecek dizelerdir.

Bu, cihaz çevrimdışıyken birden fazla mesajın gönderildiği ve kullanıcının yalnızca cihaz açıldığında en son mesajı görmesini istediğiniz senaryolarda faydalıdır.

Öncelik

İsteğe bağlı

Aciliyet, push hizmetine bir mesajın kullanıcı için ne kadar önemli olduğunu belirtir. Bu, yalnızca pil seviyesi düşük olduğunda önemli mesajlar için cihazı uyandırarak kullanıcının cihazının pil ömrünü korumaya yardımcı olmak amacıyla push hizmeti tarafından kullanılabilir.

Başlık değeri aşağıda gösterildiği gibi tanımlanır. Varsayılan değer normal'tir.

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

Her şey bir arada

Tüm bunların işleyiş şekliyle ilgili başka sorularınız varsa kitaplıkların push mesajlarını nasıl tetiklediğini dilediğiniz zaman web-push-libs org adresinden görebilirsiniz.

Şifrelenmiş bir yük ve yukarıdaki üstbilgileriniz olduğunda, PushSubscription içinde endpoint adresine bir POST isteği göndermeniz yeterlidir.

Peki bu POST isteğinin yanıtıyla ne yapacağız?

Push hizmetinden yanıt

Bir push hizmetine istek gönderdikten sonra, isteğin başarılı olup olmadığını öğrenmek için yanıtın durum kodunu kontrol etmeniz gerekir.

Durum Kodu Açıklama
201 Oluşturuldu. Push mesajı gönderme isteği alındı ve kabul edildi.
429 Çok fazla istek var. Yani uygulama sunucunuz, bir itme hizmetiyle ilgili hız sınırına ulaştı. Push hizmeti, başka bir istek gönderilebilmesi için ne kadar süre geçmesi gerektiğini belirten bir "Retry-After" başlığı içermelidir.
400 Geçersiz istek. Bu genellikle başlıklarınızdan birinin geçersiz veya yanlış biçimlendirilmiş olduğu anlamına gelir.
404 Bulunamadı. Bu, aboneliğin süresinin dolduğu ve kullanılamayacağını gösterir. Bu durumda, "PushSubscription"ı silmeniz ve istemcinin kullanıcıyı yeniden kaydetmesini beklemeniz gerekir.
410 Gitti. Abonelik artık geçerli değil ve uygulama sunucusundan kaldırılmalıdır. Bu durum, bir "PushSubscription" üzerinde "unsubscribe" çağrısı yapılarak yeniden üretilebilir.
413 Yük boyutu çok büyük. Bir push hizmetinin desteklemesi gereken minimum yük boyutu 4096 bayt (veya 4 kb) olmalıdır.

HTTP durum kodları hakkında daha fazla bilgi için Web Push standardını (RFC8030) da okuyabilirsiniz.

Sonraki adımlar

Codelab uygulamaları