首先,我已经检查这些问题,没有任何的运气:网页推送与VAPID:400/401未经授权注册
- Web Push API Chrome, returning "Unauthorized Registration"
- [WebPush][VAPID] Request fails with 400 UnauthorizedRegistration
我想为我正在处理的Web应用程序实现Web推送通知。目前,我已经实现了以下目标:
- 创建一个VAPID密钥对(with this guide)。
- 注册服务人员(只有服务人员,我认为
manifest.json
不再需要)。 - 订阅用户到服务器(订阅数据将存储在数据库中)。
- 发送带有webpush宝石的推送通知。
设置后,一切工作正常(在本地和远程机器上)。但是,在几个小时之后(12到24小时之内),通知将停止在远程计算机上工作(本地主机完美工作)。
- 铬:
UnauthorizedRegistration 400
(没有额外的信息),在此时间之后,从服务器端(Rails)的发送推送通知时,下面的错误抛出。 - 火狐:
{"code": 401, "errno": 109, "error": "Unauthorized", "more_info": "http://autopush.readthedocs.io/en/latest/http.html#error-codes", "message": "Request did not validate Invalid bearer token: Auth > 24 hours in the future"}
后出现这个错误,我试图退订和重新订阅每个页面的访问用户。重新订阅完成后,数据库上的订阅字段会更新,但错误仍在抛出,具有相同的信息。浏览器和服务人员都不会抛出错误。
我试图通过在Chrome开发工具控制台上放置一些js代码,取消注册服务工作者并重置推送通知权限来手动强制重新签名,但没有任何方法可以解决此错误。我只能修复这个错误创建一个新的VAPID密钥对重新启动远程机器。在机器启动后,我又有12-24小时再次失败。另外,通知发送过程在导航服务器(nginx +独角兽),导轨控制台,也不irb上都不工作。
我不知道从哪里开始。甚至最糟糕的是,我只能每天尝试一次修复,因为它每隔24小时就会中断一次。我想我需要一些外部帮助,对问题有一个全新的认识。我错过了什么吗? VAPID是否有任何操作系统依赖关系需要重新启动?
下面是一些可能有用的代码片段。对不起,我已经做了大量的修改,试图使它工作。
服务工作者登记:
serviceWorkerRegistration = null
registerServiceWorker = ->
if 'serviceWorker' of navigator && 'PushManager' of window
navigator.serviceWorker.register("<js url>").then (reg) ->
serviceWorkerRegistration = reg
checkSubscription()
.catch (error) ->
console.warn 'Service Worker Error', error
else
console.warn 'Push messaging is not supported'
registerServiceWorker()
用户订阅并重新订阅
# Refresh user subscription (unsub + sub)
refreshUserSubscription = ->
unsubscribeUser(subscribeUser)
# Subscribe the user to the push server
subscribeUser = ->
return if !serviceWorkerRegistration
# Subscribe
serviceWorkerRegistration.pushManager.subscribe
userVisibleOnly: true
applicationServerKey: urlB64ToUint8Array('...')
.then (subscription) ->
pushSubscription subscription
.catch (err) ->
console.warn 'Failed to subscribe the user: ', err
# Unsubscribe user
unsubscribeUser = (callback)->
return unless serviceWorkerRegistration
serviceWorkerRegistration.pushManager.getSubscription().then (subscription) ->
if subscription
subscription.unsubscribe().then(callback)
else
callback()
.catch (error) ->
console.warn 'Error unsubscribing', error
# Push subscription to the web app
pushSubscription = (subscription) ->
data = if subscription then subscription.toJSON() else {}
$.post "<back-end endpoint>", subscription: data
# Fetch current subscription, and push it.
checkSubscription =() ->
serviceWorkerRegistration.pushManager.getSubscription()
.then (subscription) ->
pushSubscription(subscription)
# I think that this should be done with promises instead of a simple timeout.
setTimeout refreshUserSubscription, 1000
服务工作者:
self.addEventListener 'push', (event) ->
title = "Example"
options = { body: "Example" }
notificationPromise = self.registration.showNotification(title, options)
event.waitUntil(notificationPromise)
网络推称:
webpush = WebPush.new({ endpoint: '...', keys: { p256dh: '...', auth: '...' } })
webpush.set_vapid_details(
"mailto:#{CONTACT_EMAIL}",
"<base64 public key>",
"<base64 private key>"
)
webpush.send_notification("foo")