带VAPID的Web推送:400/401未经授权的注册 [英] Web Push with VAPID: 400/401 Unauthorized Registration

查看:108
本文介绍了带VAPID的Web推送:400/401未经授权的注册的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我已经检查了这些问题,没有任何运气:

First of all, I've already check these questions, without any luck:

  • Web Push API Chrome, returning "Unauthorized Registration"
  • [WebPush][VAPID] Request fails with 400 UnauthorizedRegistration

我正在尝试为我正在使用的Web应用程序实现Web推送通知.目前,我已经实现了以下目标:

I am trying to implement web push notifications for a web app that I'm working on. Currently, I've achieved the following goals:

  • 创建VAPID密钥对(与此指南).
  • 注册服务人员(仅服务人员,我认为不再需要manifest.json).
  • 将用户订阅到服务器(订阅数据将存储在数据库中).
  • 使用 webpush gem发送推送通知.
  • Create a VAPID keys pair (with this guide).
  • Register a service worker (only a service worker, I think that manifest.json is no longer required).
  • Subscribe the user to the server (subscription data will be stored in the database).
  • Send a push notification with webpush gem.

设置后,一切正常(在localhost和远程计算机上).但是,在几个小时后(12到24小时之间),通知将在远程计算机上停止工作(localhost可以正常工作).在此之后,从服务器端(Rails)发送推送通知时会引发以下错误:

After setting it up, everything works fine (on localhost and on a remote machine). However, after some hours (between 12 and 24 hours), the notifications stop working on the remote machine (localhost works perfectly). After that time, the following errors are thrown when sending the push notifications from the server side (Rails):

  • 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"}
  • Chrome: UnauthorizedRegistration 400 (no extra info).
  • 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上的subscription字段将更新,但仍会引发错误,并带有相同的信息.浏览器或服务工作者均不会引发任何错误.

After this error appeared, I tried to unsubscribe and resubscribe the user on every page visit. The subscription field on the db is updated after the resubscription is done, but the error is still being thrown, with the same information. No errors are thrown on the browser, nor service worker.

我尝试通过在Chrome Dev Tools控制台上放置一些js代码,取消注册服务人员并重置推送通知权限来手动强制重新订阅,但没有任何方法可以解决该错误.我只能通过 创建新的VAPID密钥对重新启动远程计算机来解决此错误.重新启动机器后,我还有12-24小时的时间才再次出现故障.此外,通知发送过程在 rails服务器(nginx +独角兽) rails控制台 irb 上均不起作用.

I've tried to force the resubscription manually by placing some js code on the Chrome Dev Tools console, unregistering the service worker, and reseting the push notification permissions, but nothing solves the error. I can only fix this error by creating a new VAPID key pair rebooting the remote machine. After crebooting the machine, I've another 12-24 hours before it fails again. Also, the notifications send process don't work neither on rails server (nginx + unicorn), rails console, nor irb.

我不知道从现在开始要去哪里.更糟糕的是,我每天只能尝试修复一次,因为它每24小时就会发生一次损坏.我认为我需要一些外部帮助来重新了解这个问题.我想念什么吗? VAPID使用并需要重新启动任何操作系统依赖性吗?

I don't know where to go from now. Even worst, I can only try fixes once a day, since it'll break every 24 hours. I think I need some external help with a fresh vision of the problem. Am I missing something? Is there any OS dependency that VAPID uses and needs to be restarted?

以下是一些有用的代码段.抱歉,一团糟,但是我做了很多修改以尝试使其正常工作.

Here are some code snippets that may be useful. Sorry for the mess, but I've done tons of modifications to try making it work.

服务人员注册:

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")

推荐答案

将过期时间从24小时(默认)更改为12小时后,现在可以正常使用了:

After changing the expiration time from 24 hours (default) to 12 hours, it now works properly:

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
  }
)

这篇关于带VAPID的Web推送:400/401未经授权的注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆