首先,我已經檢查這些問題,沒有任何的運氣:網頁推送與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")