Understanding How to Store Web Push Endpoints

I'm trying to get started implementing Web Push in one of my apps. In the examples I have found, the client's endpoint URL is generally stored in memory with a comment saying something like:

In production you would store this in your database...

Since only registered users of my app can/will get push notifications, my plan was to store the endpoint URL in the user's meta data in my database. So far, so good.

The problem comes when I want to allow the same user to receive notifications on multiple devices. In theory, I will just add a new endpoint to the database for each device the user subscribes with. However, in testing I have noticed that endpoints change with each subscription/unsubscription on the same device. So, if a user subscribes/unsubscribes several times in a row on the same device, I wind up with several endpoints saved for that user (all but one of which are bad).

From what I have read, there is no reliable way to be notified when a user unsubscribes or an endpoint is otherwise invalidated. So, how can I tell if I should remove an old endpoint before adding a new one?

What's to stop a user from effectively mounting a denial of service attack by filling my db with endpoints through repeated subscription/unsubscription?

That's more meant as a joke (I can obvioulsy limit the total endpoints for a given user), but the problem I see is that when it comes time to send a notification, I will blast notification services with hundreds of notifications for invalid endpoints.


I want the subscribe logic on my server to be:

  • Check if we already have an endpoint saved for this user/device combo
  • If not add it, if yes, update it
  • The problem is that I can't figure out how to reliably do #1.


    I will just add a new endpoint to the database for each device the user subscribes with

    The best approach is to have a table like this:

    endpoint | user_id
    
  • add an unique constraint (or a primary key) on the endpoint : you don't want to associate the same browser to multiple users, because it's a mess (if an endpoint is already present but it has a different user_id , just update the user_id associated to it)
  • user_id is a foreign key that points to your users table
  • if a user subscribes/unsubscribes several times in a row on the same device, I wind up with several endpoints saved for that user (all but one of which are bad).

    Yes, unfortunately the push API has a wild unsubscription mechanism and you have to deal with it.

    The endpoints can expire or can be invalid (or even malicious, like android.chromlum.info ). You need to detect failures (using the HTTP status code, timeouts, etc.) when you try to send the push message from your application server. Then, for some kind of failures (permanent failures, like expiration) you need to delete the endpoint.

    What's to stop a user from effectively mounting a denial of service attack by filling my db with endpoints through repeated subscription/unsubscription?

    As I described above, you need to properly delete the invalid endpoints, once you realize that they are expired or invalid. Basically they will produce at most one invalid request. Moreover, if you have high throughput, it takes only a few seconds for your server to make requests for thousands of endpoints.

    My suggestions are based on a lot of experiments and thinking done when I was developing Pushpad.

    链接地址: http://www.djcxy.com/p/40258.html

    上一篇: 生锈,WebAssembly和传递参数以增加总内存

    下一篇: 了解如何存储Web推送端点