安全,有弹性的重新订阅,用于服务工作者的推送通知

时间:2016-02-08 22:21:21

标签: meteor web push

我正在尝试实现一个为Web应用程序执行推送通知的服务工作者。我希望系统具有弹性,因为它不断发送推送通知,而无需用户定期与应用程序进行交互。为此,我正在关注pushsubscriptionchange事件,但我不确定如何在服务工作者的有限约束内工作。

方法1:回复我的应用

我当前的代码捕获此事件,创建新订阅并通过postMessage将其发送回客户端。然后客户端调用我的后端并注册新的订阅端点。

这似乎是最优雅的方式,除了我认为它需要一个打开的标签。如果用户几天没有办理登机手续但仍然对获取推送通知感兴趣,那么现有订阅最终会超时,并且无法通知应用有关新获得的端点的信息。

方法2:安全地调用REST端点

然后,我有了将REST端点添加到接受更新订阅的应用程序的想法。一个复杂的问题是该应用程序使用Meteor,因此服务工作者无法访问其自身的基础设施(例如DDP协议)。

我的想法是每当添加新订阅时生成UUID作为令牌。然后,服务工作者可以fetch将端点作为查询参数传递并发送新的端点/密钥。然后创建一个新令牌,删除旧令牌,并注册新推送端点。

不幸的是,我不确定如何以客户端和服务工作者可以共享的方式存储令牌。服务人员无法使用本地存储。缓存API似乎针对实际请求,而不是简单的键/值。 IndexDB可供服务工作者使用,但我真的只想存储一个键入“pushEndpointToken”之类的UUID。除了打开数据库并为此单个键/值声明模式之外,我真的没有其他选择吗?

有没有第三种方法我不考虑?我只想确保我的应用程序始终具有有效的推送端点,只要用户想要从其接收通知。

感谢。

1 个答案:

答案 0 :(得分:0)

<强>更新

当服务工作程序停止并稍后唤醒时,运行时变量将丢失。您需要使用持久存储,例如IndexedDB或cookie(将令牌附加到请求)。

我可以推荐idb-keyval - 我在app(写)和服务工作者(读)之间共享一个数据库。

老答案:

您可以使用PostMessage API将令牌发送到服务工作者 这是一个概念,我还在努力

<强>服务worker.js:

const runtimeVars = {
  token: undefined,
}

self.addEventListener('message', event => {

  // Probably no need for this check
  if (event.origin !== self.origin) {
    return
  }

  if (event.data.token) {
    runtimeVars.token = event.data.token
  }
})

self.addEventListener('pushsubscriptionchange', event => {
  // Fire unregister request with runtimeVars.token
})

<强> app.js

const controller = window.navigator.serviceWorker.controller

if (controller)
  // At app dispatch
  controller.postMessage({token: localStorage.getItem('token'})

  // After login pass API token to service worker
  controller.postMessage({token})

  // After logout, nullify token
  controller.postMessage({token: undefined})
}