Understanding How to Store Web Push Endpoints

I am trying to start implementing Web Push in one of my applications. In the examples I found, the client endpoint URL is usually stored in memory with a comment saying something like:

During the production process, you would store this in your database ...

Since only registered users of my application can receive push notifications, my plan was to store the endpoint URL in the user metadata in my database. So far so good.

The problem occurs when I want to allow the same user to receive notifications on multiple devices. Theoretically, I simply add a new endpoint to the database for each device that the user subscribed to. However, when testing, I noticed that the endpoints change with each subscription / unsubscription on the same device. Thus, if a user subscribes / does not subscribe several times in a row on the same device, I finish working with several endpoints saved for this user (all but one of which are bad). A.

From what I read , there is no reliable way to get a notification when a user cancels a subscription or the endpoint is otherwise invalid. So, how can I determine if an old endpoint should be deleted before adding a new one?

What prevents the user from effectively establishing a denial of service attack by populating my db with endpoints by re-subscribing / unsubscribing?

This is more like a joke (I can limit the common endpoints for a given user), but the problem I see is that when the time comes to send a notification, I will spoof the notification services with hundreds of notifications about invalid endpoints.


I want the subscription logic on my server to be:

  • Make sure we already have the endpoint saved for this user / device combination.
  • If not add it, if yes, update it

The problem is that I cannot figure out how to reliably make # 1.

+5
source share
1 answer

I will simply add a new endpoint to the database for each device that the user signs

The best approach is to have a table like this:

endpoint | user_id 
  • add a unique constraint (or primary key) to the endpoint : you do not want to associate the same browser with multiple users, because it is a mess (if the endpoint is already present but has a different user_id , just update the user_id associated with it)
  • user_id is a foreign key pointing to your users table.

if a user subscribes / does not subscribe several times in a row on the same device, I finish working with several endpoints saved for this user (all but one of which are bad). A.

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

Endpoints may expire or may be invalid (or even malicious, for example android.chromlum.info ). When you try to send a push message from your application server, you need to detect failures (using the HTTP status code, timeouts, etc.). Then for any failures (persistent failures, such as expiration) you need to delete the endpoint.

What prevents the user from effectively establishing a denial of service attack by populating my db with endpoints by re-subscribing / unsubscribing?

As I said above, you need to correctly remove invalid endpoints as soon as you realize that they have expired or were invalid. Basically, they will produce no more than one invalid request. Moreover, if you have high bandwidth, it only takes a few seconds for your server to query thousands of endpoints.

My suggestions are based on a lot of experimentation and reflection when I developed Pushpad .

+2
source

Source: https://habr.com/ru/post/1271131/


All Articles