Service Worker - 使用 VAPID prv/pub 键推送通知

Posted

技术标签:

【中文标题】Service Worker - 使用 VAPID prv/pub 键推送通知【英文标题】:Service Worker - Push notification with VAPID prv/pub keys 【发布时间】:2018-05-16 01:44:39 【问题描述】:

几年前,我通过在 Firebase 上注册一个应用程序,并将注册号用作服务器端应用程序的 manifest.json 文件的一部分,在我正在从事的项目中使用 service worker 实现了推送通知。在那种情况下,我请求用户允许通知,浏览器注册一次,保存在服务器端,一切正常。

我现在正在尝试实施类似的解决方案,但使用 VAPID (https://developers.google.com/web/ilt/pwa/introduction-to-push-notifications#using_vapid)。 浏览器正确注册,将注册发送到服务器端应用程序,应用程序能够发送推送通知。 我遇到的问题是,至少 24 小时后,当我尝试向已注册的订阅发送推送通知时,我收到 InvalidSubscription 响应(410 NotRegistered)。 使用 VAPID,浏览器注册会在几个小时后过期吗?我需要每隔一定时间进行一次新注册吗?如果是,如何?例如,如果用户在一天左右的时间内从未重新访问该网站,我如何能够继续向他们发送通知?对于我遇到的这个问题,我找不到任何明确的参考。

这是我在 SW 中用于获取浏览器注册的 JS 代码:

function postPushReg(sub)
  var rawKey = sub.getKey ? sub.getKey('p256dh') : '';
  var key = rawKey ?
        btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) :
        '';
  var rawAuthSecret = sub.getKey ? sub.getKey('auth') : '';
  var authSecret = rawAuthSecret ?
                   btoa(String.fromCharCode.apply(null, new Uint8Array(rawAuthSecret))) :
                   '';
  fetch('https://XXXXX', 
    method: 'post',
    headers: 'Content-type': 'application/json',
    body: JSON.stringify(endpoint: sub.endpoint, key: key, authSecret: authSecret),
  );


self.addEventListener('install', function(event)
  self.registration.pushManager.getSubscription()
  .then(function(sub)
    if (sub) return postPushReg(sub);
    return self.registration.pushManager.subscribe(userVisibleOnly: true,
                                    applicationServerKey: urlB64ToUint8Array('XXX'))
                                    .then(function(sub)
                                      postPushReg(sub);
                                    );
  );
);

self.addEventListener('push', function(e)
  ...
);

这是我用来发送通知的 Rails/Ruby 服务器端 gem (webpush):

Webpush.payload_send(
        message: "msg",
        endpoint: j['endpoint'],
        p256dh: j['key'],
        auth: j['authSecret'],
        vapid: 
          subject: "mailto:XXXX",
          public_key: "XXX",
          private_key: "XXX",
        
      )

同样,在最初的几个小时内一切正常,然后我收到 410 NotRegistered 响应。

【问题讨论】:

【参考方案1】:

尝试此处发布的相同建议:Web Push with VAPID: 400/401 Unauthorized Registration,现在工作正常。我只获得了一次浏览器注册,2天后它仍然可以正常工作

【讨论】:

以上是关于Service Worker - 使用 VAPID prv/pub 键推送通知的主要内容,如果未能解决你的问题,请参考以下文章

web worker 与 service worker

使用 Angular Service Worker 发送 JWT 令牌

使用Service Worker和离线缓存Cache

Service-Worker addEventListener,如何使用事件参数?

带有 VAPID 的 Web 推送:400/401 未经授权的注册

Service Worker的缓存时机与缓存策略