Web Push Protokolü

Matt Gaunt

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

Yani ağ isteklerinde bulunuyorlar ve bu isteklerin doğru biçimde olmalarını sağlıyorlar. 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 kendini nasıl tanımlayabileceği ve şifrelenmiş yükün ve ilişkili verilerin nasıl gönderildiği özetlenmektedir.

Bu, web push'un pek hoş bir tarafı değildir ve şifreleme konusunda uzman değilim, ancak bu kitaplıkların arka planda neler yaptığını bilmek işe yarayacak olduğu için her bir parçaya bakalım.

Uygulama sunucusu anahtarları

Bir kullanıcıya abone olduğumuzda, applicationServerKey iletiriz. Bu anahtar push hizmetine iletilir ve kullanıcıya abone olan uygulamanın aynı zamanda push mesajlarını tetikleyen uygulama olup olmadığını kontrol etmek için kullanılır.

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

Tüm bunlar ne anlama geliyor ve tam olarak 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 push hizmetine POST isteğinde üstbilgi olarak gönderilir.
  3. Push hizmeti, alınan bilgilerin ortak anahtarla ilgili özel anahtar tarafından imzalanıp imzalanmadığını kontrol etmek için pushManager.subscribe() kaynağından aldığı saklanan ortak anahtarı kullanır. Unutmayın: Ortak anahtar, abone olma çağrısına geçirilen applicationServerKey değeridir.
  4. İmzalanmış bilgiler geçerliyse push hizmeti, kullanıcıya push mesajını gönderir.

Bu bilgi akışının bir örneğini aşağıda görebilirsiniz. (Genel ve özel anahtarları belirtmek için sol alt kısımdaki göstergeye dikkat edin.)

İleti gönderirken özel uygulama sunucu anahtarının nasıl kullanıldığını gösteren resim

İstekteki üstbilgiye eklenen "imzalı bilgi" bir JSON Web Token'dır.

JSON web jetonu

JSON web jetonu (veya kısaca JWT), alıcının kimin gönderdiğini doğrulayabilmesi için üçüncü taraflara bir mesaj gönderme yoludur.

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

https://jwt.io/ adresinde imzalama işlemini sizin için gerçekleştirebilecek pek çok kitaplık bulunmaktadır. Mümkün olan yerlerde bunları yapmanızı öneririz. Eksiksiz olması için imzalı bir JWT'nin manuel olarak nasıl oluşturulacağını görelim.

Web push ve imzalı JWT'ler

İmzalanmış JWT sadece bir dizedir ancak noktalarla birleştirilen üç dize olarak düşünülebilir.

JSON Web Jetonu'ndaki dizelerin çizimi

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

İlk dize, imzayı oluşturmak için hangi algoritmanın kullanıldığını gösteren JWT'nin kendisiyle ilgili bilgilerdir.

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

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

İkinci dize, JWT Verileridir. Burada JWT'yi gönderen kişi, mesajın kime gönderildiği ve ne kadar süreyle geçerli olduğu hakkında bilgi verilir.

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"yi, yani JWT'nin kime yönelik olduğunu belirtir. Web push için kitle, push hizmetidir. Bu yüzden bunu push hizmetinin kaynağına ayarladık.

exp değeri, JWT'nin son geçerlilik tarihidir. Bu sayede, merak edenlerin JWT'ye müdahale etmeleri durumunda JWT'yi yeniden kullanmaları engellenir. Geçerlilik süresi, saniye cinsinden bir zaman damgasıdır ve artık 24 saat olmamalıdır.

Node.js'de geçerlilik sonu aşağıdakiler kullanılarak ayarlanır:

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

Gönderme uygulaması ve push hizmeti arasındaki saat farklarıyla ilgili herhangi bir sorun yaşanmaması için 24 saat yerine 12 saat gerekir.

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

JWT Info'da olduğu gibi, JWT Verileri de URL güvenli base64 dizesi olarak kodlanır.

Üçüncü dize olan imza, ilk iki dizenin (JWT Bilgisi ve JWT Verileri) alınması, bunların "imzasız jeton" adını verdiğimiz nokta karakteriyle birleştirilmesi ve imzalanması sonucunda ortaya çıkar.

İ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ı şu şekilde 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);
});

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

İmzalanmış JWT (noktalarla birleştirilmiş üç dize), web push hizmetine Authorization başlığı olarak ve başına WebPush eklenmiş şekilde gönderilir. Örneğin:

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

Web Push Protokolü, ortak uygulama sunucusu anahtarının Crypto-Key üstbilgisinde, URL güvenli base64 kodlamalı dize olarak ve başına p256ecdsa= eklenmiş olarak gönderilmesi gerektiğini belirtir.

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

Yük Şifreleme

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

Diğer push hizmetlerini kullananların sık sorduğu sorulardan biri, web push yükünün neden şifrelenmesi gerektiğidir? Yerel uygulamalarda push mesajları, verileri düz metin olarak gönderebilir.

Web push hizmetinin güzel taraflarından biri, tüm push hizmetleri aynı API'yi (web push protokolü) kullandığından geliştiricilerin push hizmetinin kim olduğuyla ilgilenmek zorunda kalmamasıdır. Doğru biçimde bir istek yapabilir ve push mesajının gönderilmesini bekleyebiliriz. Bunun olumsuz tarafı ise geliştiricilerin güvenilir olmayan bir push hizmetine mesaj gönderebilmesidir. Yükü şifreleyen bir push hizmeti, gönderilen verileri okuyamaz. Bilgilerin şifresini yalnızca tarayıcı çözebilir. Bu, kullanıcının verilerini korur.

Yükün şifrelemesi, Message Encryption (İleti Şifreleme) spesifikasyonunda tanımlanmıştır.

Push mesajı yükünü şifrelemenin özel adımlarına bakmadan önce, şifreleme işlemi sırasında kullanılacak bazı tekniklere değinelim. (Push şifrelemeyle ilgili mükemmel makalesi için Mat Scales'e büyük şapkalı bir ipucu veriyoruz.)

ECDH ve HKDF

Şifreleme işlemi boyunca hem ECDH hem de HKDF kullanılır ve bilgilerin şifrelenmesi açısından çeşitli avantajlar sunulur.

ECDH: Elips Biçimli Eğri Diffie-Hellman anahtar değişimi

Bilgi paylaşmak isteyen iki kişiniz olduğunu düşünün: Aylin ve Ali. Hem Ayşe'nin hem de Ali'nin kendi genel ve özel anahtarları vardır. Alice ve Bob ortak anahtarlarını birbirleriyle paylaşırlar.

ECDH ile oluşturulan anahtarların kullanışlı özelliği, Ayşe'nin kendi özel anahtarını ve İbrahim'in ortak anahtarını kullanarak "X" gizli anahtar değerini oluşturabilmesidir. Bob da aynısını yapabilir ve aynı "X" değerini bağımsız bir şekilde oluşturmak için kendi özel anahtarını ve Ayşe'nin ortak anahtarını alabilir. Bu da "X"in paylaşılan bir sır olduğunu ve Alice ile Bob'un yalnızca ortak anahtarlarını paylaşmak zorunda kalmıştı. Artık Bob ve Alice, "X" işaretini kullanarak aralarındaki mesajları şifreleyebilir ve şifresini çözebilir.

ECDH, bildiğim kadarıyla, bu paylaşılan gizli anahtarı "X" yapma "özelliğini" sağlayan eğrilerin özelliklerini tanımlıyor.

Bu makalede ECDH hakkında genel bilgi verilmektedir. Daha fazla bilgi için bu videoya göz atabilirsiniz.

Kod söz konusu olduğunda, çoğu dilde / platformda bu anahtarları oluşturmayı kolaylaştıran kitaplıklar bulunur.

Düğümde ş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 kısa ve öz bir açıklama bulunmaktadır:

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

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

Bu şifrelemeyi tanımlayan spesifikasyon, karma algoritmamız olarak SHA-256'nın kullanılmasını gerektirir ve web push'ta HKDF için oluşturulan anahtarlar 256 bitten (32 bayt) uzun olmamalıdır.

Düğümde bu şu şekilde 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);
}

Mat Scale'in bu örnek kodla ilgili makalesine şapka ipucu.

Bu, ECDH ve HKDF'yi genel olarak kapsar.

ECDH, ortak anahtarları paylaşmanın ve paylaşılan bir gizli anahtar oluşturmanın güvenli bir yoludur. HKDF, güvenli olmayan malzemeyi alıp güvenli hale getirmenin bir yoludur.

Bu, yükümüzün şifrelenmesi sırasında kullanılır. Şimdi, girdi olarak ne aldığımıza ve bunun nasıl şifrelendiğine bakalım.

Girişler

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

  1. Yükün kendisi.
  2. PushSubscription öğesinden auth gizli anahtarı.
  3. PushSubscription öğesinden p256dh anahtarı.

PushSubscription öğesinden alınan auth ve p256dh değerlerini görmüştük, ancak hızlı bir şekilde unutmamak için abonelik söz konusu olduğunda şu değerlere ihtiyacımız olacaktı:

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

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

auth değeri gizli bilgi olarak ele alınmalı ve uygulamanızın dışında paylaşılmamalıdır.

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

Bu üç değer (auth, p256dh ve payload) giriş olarak gereklidir ve şifreleme işleminin sonucu; şifrelenmiş yük, bir takviye değer ve yalnızca verilerin şifrelenmesi için kullanılan bir ortak anahtar olur.

Tuz

Takviye değer, 16 bayt rastgele veri olmalıdır. NodeJS'de bir takviye değer oluşturmak için aşağıdakileri yaparız:

const salt = crypto.randomBytes(16);

Genel / Gizli Anahtarlar

Genel ve özel anahtarlar P-256 elips biçimli eğri kullanılarak oluşturulmalıdır. Düğümde aşağıdaki gibidir:

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

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

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

Yük, kimlik doğrulama sırrı ve abonelik ortak anahtarı girdi olarak, yeni oluşturulan bir tuz ve yerel anahtar kümesiyle ş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 (Ali ve İbrahim ile ilgili ECDH açıklamasını hatırlıyor musunuz? Onun gibi).

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

Bu değer, bir sonraki adımda sözde rastgele anahtarın (PRK) hesaplanmasında kullanılır.

Sözde rastgele anahtar

Sözde Rastgele Anahtar (PRK), push aboneliğinin kimlik doğrulama gizli anahtarı ile yeni 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çin olduğunu merak ediyor olabilirsiniz. Kısacası, bunun net bir amacı yoktur, ancak tarayıcılar gelen bir iletinin şifresini çözebilir ve beklenen içerik kodlamasını arayabilir. \0, Arabelleğin sonuna 0 değerine sahip bir bayt ekler. Bu, mesajın şifresini çözen tarayıcılar tarafından, içerik kodlaması için bu kadar çok bayt, ardından 0 değerine sahip bir bayt ve onu izleyen şifrelenmiş veriler tarafından beklenmektedir.

Sözde Rastgele Anahtarımız, HKDF üzerinden kimlik doğrulamayı, paylaşılan sırrı ve kodlama bilgisinin bir parçasını çalıştırır (yani bilgiyi kriptografik olarak 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. Bu aslında abonelik ortak anahtarını ve yerel ortak anahtarını 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ı, bunu takip eden anahtarın kendisi, yerel ortak anahtarın bayt sayısı ve anahtarın kendisi gelir.

Bu bağlam değeri sayesinde tek seferlik rastgele sayı ve içerik şifreleme anahtarı (CEK) oluştururken kullanabiliriz.

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

Tek seferlik, yalnızca bir kez kullanılması gerektiği için tekrar oynama 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 baytlarca veri oluşturmamız gerekir. CEK, bir içerik kodlama dizesi ve ardından az önce hesapladığımız içerik arabelleğidir:

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ştirerek 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 bize tek seferlik rastgele sayı ve içerik şifreleme anahtarımızı verir.

Şifrelemeyi gerçekleştirme

Artık içerik şifreleme anahtara sahip olduğumuza göre yükü şifreleyebiliriz.

Anahtar olarak içerik şifreleme anahtarını ve tek seferlik rastgele sayı bir başlatma vektörü olan bir AES128 şifresi oluştururuz.

Düğümde bu ş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 belirlememiz gerekir. Dolgu eklemek istememizin nedeni, bu dolgunun kulak misafiri kişilerin yük boyutuna göre mesajların "türlerini" belirleyebilmesi riskinin önlenmesidir.

Herhangi bir ek dolgunun uzunluğunu belirtmek için iki baytlık dolgu eklemeniz gerekir.

Örneğin, dolgu eklemediyseniz, değeri 0 olan iki baytınız olur (doldurma yoktur), bu iki bayttan sonra yükü okumuş olursunuz. 5 baytlık dolgu eklediyseniz ilk iki baytın değeri 5 olacaktır. Dolayısıyla, tüketici 5 bayt daha 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);

Daha sonra, dolgumuzu ve yükümüzü bu şifreden geçiririz.

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

Şifrelenmiş yükümüz artık elimizde. Yaşasın!

Geriye sadece bu yükün push hizmetine nasıl gönderileceğini belirlemek kaldı.

Şifrelenmiş yük başlıkları ve gövde

Bu şifrelenmiş yükü push hizmetine göndermek için POST isteğimizde birkaç farklı başlık tanımlamamız gerekir.

Şifreleme başlığı

"Şifreleme" başlığı, yükü şifrelemek için kullanılan salt değerini içermelidir.

16 baytlık takviye değer, aşağıdaki gibi base64 URL için güvenli bir şekilde kodlanmalı ve Şifreleme başlığına eklenmelidir:

Encryption: salt=[URL Safe Base64 Encoded Salt]

Şifreleme Anahtarı başlığı

"Uygulama Sunucusu Anahtarları" bölümünde, ortak uygulama sunucusu anahtarını içerecek Crypto-Key üstbilgisinin kullanıldığını tespit ettik.

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

Elde edilen üstbilgi aşağıdaki gibi 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ü, uzunluğu ve kodlama başlıkları

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

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

Bu başlıklar ayarlandığında şifrelenmiş yükü isteğimizin gövdesi olarak göndermemiz gerekir. Content-Type öğesinin application/octet-stream olarak ayarlandığına dikkat edin. Bunun nedeni, şifrelenmiş yükün baytlardan oluşan bir akış olarak gönderilmesi gerekmesidir.

NodeJS'de bu işlem şu şekilde yapılır:

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

Daha fazla başlık?

JWT / Uygulama Sunucusu Anahtarları için kullanılan üst bilgileri (yani uygulamayı push hizmetiyle tanımlama) ve şifrelenmiş bir yük göndermek için kullanılan başlıkları ele aldık.

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

TTL üstbilgisi

Zorunlu

TTL (veya geçerlilik süresi), push iletinizin push hizmetinde yayınlanmasını istediğiniz saniye sayısını belirten bir tam sayıdır. TTL öğesinin süresi dolduğunda mesaj push hizmet sırasından 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 teslim etmeye çalışır ancak cihaza ulaşılamıyorsa mesajınız push hizmeti sırasından hemen çıkarılır.

Teknik olarak bir push hizmeti, istemesi halinde push mesajlarının TTL değerini azaltabilir. Bir push hizmetinin yanıtındaki TTL üst bilgisini inceleyerek bunun olup olmadığını anlayabilirsiniz.

Konu

İsteğe bağlı

Konular, eşleşen konu adlarına sahip bekleyen mesajları yeni bir mesajla değiştirmek için kullanılabilecek dizelerdir.

Bu özellik, bir cihaz çevrimdışıyken birden fazla mesajın gönderildiği senaryolarda faydalıdır ve kullanıcının yalnızca cihaz açıkken en son mesajı görmesini istediğinizde yararlı olur.

Öncelik

İsteğe bağlı

Aciliyet, push hizmeti için bir iletinin kullanıcı için ne kadar önemli olduğunu belirtir. Push hizmeti, kullanıcı cihazının pil ömrünü korumaya yardımcı olmak için bu hizmeti yalnızca önemli mesajlar için pil azaldığında kullanılabilir.

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

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

Hepsi bir arada

Tüm bunların nasıl işlediğine dair başka sorularınız varsa kitaplıkların web-push-libs kuruluşunda push mesajlarını nasıl tetiklediğini görebilirsiniz.

Şifrelenmiş bir yük ve yukarıdaki başlıklara sahip olduğunuzda PushSubscription içinde endpoint için bir POST isteği göndermeniz yeterlidir.

Peki bu POST isteğine verilen yanıtı nasıl değerlendireceğiz?

Push hizmetinden yanıt

Push hizmetine istekte bulunduktan sonra, yanıtın durum kodunu kontrol etmeniz gerekir. Bu kod, isteğin başarılı olup olmadığını gösterir.

Durum Kodu Açıklama
201 Oluşturuldu. Push mesajı gönderme isteği alındı ve kabul edildi.
429 Çok fazla istek var. Bu, uygulama sunucunuzun bir push hizmetiyle hız sınırına ulaştığı anlamına gelir. Push hizmeti, başka bir isteğin ne kadar süre sonra yapılabileceğini belirtmek için 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ğunu ve kullanılamadığını gösterir. Bu durumda, "PushSubscription"ı silmeniz ve istemcinin kullanıcıya yeniden abone olmasını beklemeniz gerekir.
410 Gitti. Abonelik artık geçerli değil ve uygulama sunucusundan kaldırılmalıdır. Bu, bir "PushSubscription"da "unsubscribe()" çağrısıyla yeniden oluşturulabilir.
413 Yük boyutu çok büyük. Bir push hizmetinin desteklemesi gereken minimum boyut yükü 4.096 bayt (veya 4 KB)'tır.

Sonraki adımlar

Code Labs