首先,我已经检查了这些问题,没有任何运气:
- Web推动API Chrome,返回"未经授权的注册"
- [webpush] [vapid]请求失败,而400未授权的registration
我正在尝试针对我正在处理的Web应用程序实现Web推送通知。目前,我已经实现了以下目标:
- 创建一个Vapid键对(使用此指南(。
- 注册服务工作者(只有服务工作者,我认为不再需要
manifest.json
(。 - 订阅用户到服务器(订阅数据将存储在数据库中(。
- 用webpush宝石发送推送通知。
设置后,一切正常(在Localhost和远程计算机上(。但是,几个小时(在12到24小时之间(后,通知停止在远程机器上工作(Localhost完美效果(。在此之后,从服务器端发送推送通知时会丢下以下错误(RAIRS(:
-
chrome:
UnauthorizedRegistration 400
(无额外信息(。 -
firefox:
{"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"}
出现此错误后,我尝试在每个页面访问时取消订阅并重新订阅用户。在重新提交后,DB上的订阅字段会更新,但是使用相同的信息仍在抛出错误。没有在浏览器上抛出错误,也没有服务工作者。
我试图通过将一些JS代码放在Chrome Dev Tools控制台上,撤销服务工作者并重置推送通知许可,但没有解决错误。我只能通过来解决此错误,创建一个新的Vapid键对重新启动远程计算机。在克里启动机器后,我又又12-24小时了,才能再次失败。另外,通知发送过程在 rails服务器(nginx Unicorn(, rails Console ,nor irb 。。。。>
我不知道从现在开始去哪里。甚至最糟糕的是,我每天只能尝试一次修复一次,因为它会每24小时破裂。我认为我需要一些外部帮助,以对该问题有了新的愿景。我想念什么吗?VAPID是否使用和需要重新启动OS依赖性?
这是一些可能有用的代码段。对不起,这是一团糟,但是我已经进行了大量的修改以使其正常工作。
服务工作者注册:
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()
用户订阅和repubscription
# 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)
Web推出呼叫:
webpush = WebPush.new({ endpoint: '...', keys: { p256dh: '...', auth: '...' } })
webpush.set_vapid_details(
"mailto:#{CONTACT_EMAIL}",
"<base64 public key>",
"<base64 private key>"
)
webpush.send_notification("foo")
将到期时间从24小时(默认(更改为12小时后,现在可以正常工作:
Webpush.payload_send(
message: "Hi!",
endpoint: "...",
p256dh: "...",
auth: "...",
vapid: {
subject: "...",
public_key: ENV['VAPID_PUBLIC_KEY'],
private_key: ENV['VAPID_PRIVATE_KEY'],
exp: 12.hours
}
)
看起来图书馆已经改变了,这就是我修复的方式:
def send_push(payload, endpoint, p256dh, auth)
Webpush.payload_send(
message: payload,
endpoint: endpoint,
p256dh: p256dh,
auth: auth,
vapid: {
public_key: '...',
private_key: '...',
expiration: 12 * 60 * 60
}
)
end
请注意,钥匙是到期的不exp,这是在几秒钟内到期的时间。