了解如何存储 Web 推送端点
Understanding How to Store Web Push Endpoints
我正在尝试开始在我的一个应用程序中实施 Web Push。在我发现的示例中,客户端的端点 URL 通常存储在内存中,并带有一条评论,如:
In production you would store this in your database...
因为只有我的应用程序 can/will 的注册用户才能收到推送通知,我的计划是将端点 URL 存储在我数据库中用户的元数据中。到目前为止,还不错。
当我想允许同一个用户在多个设备上接收通知时,问题就来了。理论上,我将为用户订阅的每个设备向数据库添加一个新端点。然而,在测试中,我注意到端点随 同一设备 上的每个 subscription/unsubscription 而变化。因此,如果一个用户 subscribes/unsubscribes 在同一台设备上连续多次,我最终会为该用户保存多个端点(除其中一个外,其他端点都不好)。
从 what I have read 开始,当用户取消订阅或端点失效时,没有可靠的方法来通知。那么,如何判断在添加新端点之前是否应该删除旧端点?
如何阻止用户通过重复 subscription/unsubscription 向我的数据库中填充端点来有效地发动拒绝服务攻击?
这更像是个玩笑(我显然可以限制给定用户的总端点),但我看到的问题是,当需要发送通知时,我会用数百个通知来发送通知服务对于无效端点。
我希望我的服务器上的订阅逻辑是:
- 检查我们是否已经为此 user/device 组合保存了端点
- 如果没有添加,如果有,更新
问题是我不知道如何可靠地执行 #1。
I will just add a new endpoint to the database for each device the user subscribes with
最好的方法是 table 像这样:
endpoint | user_id
- 在
endpoint
上添加唯一约束(或主键):您不想将同一个浏览器关联到多个用户,因为它是一团糟(如果端点已经存在但它有一个不同的 user_id
,只需更新与之关联的 user_id
)
user_id
是指向您的用户的外键 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).
是的,不幸的是推送API有a wild unsubscription mechanism,你必须处理它。
端点可能会过期或无效(甚至是恶意的,如 android.chromlum.info
)。当您尝试从您的应用程序服务器发送推送消息时,您需要检测故障(使用 HTTP 状态代码、超时等)。然后,对于某种故障(永久性故障,如过期),您需要删除端点。
What's to stop a user from effectively mounting a denial of service attack by filling my db with endpoints through repeated subscription/unsubscription?
如上所述,您需要正确删除无效端点,一旦您意识到它们已过期或无效。基本上他们最多会产生一个无效请求。此外,如果您的吞吐量很高,您的服务器只需几秒钟就可以向数千个端点发出请求。
我的建议是基于我在开发时所做的大量实验和思考 Pushpad。
我正在尝试开始在我的一个应用程序中实施 Web Push。在我发现的示例中,客户端的端点 URL 通常存储在内存中,并带有一条评论,如:
In production you would store this in your database...
因为只有我的应用程序 can/will 的注册用户才能收到推送通知,我的计划是将端点 URL 存储在我数据库中用户的元数据中。到目前为止,还不错。
当我想允许同一个用户在多个设备上接收通知时,问题就来了。理论上,我将为用户订阅的每个设备向数据库添加一个新端点。然而,在测试中,我注意到端点随 同一设备 上的每个 subscription/unsubscription 而变化。因此,如果一个用户 subscribes/unsubscribes 在同一台设备上连续多次,我最终会为该用户保存多个端点(除其中一个外,其他端点都不好)。
从 what I have read 开始,当用户取消订阅或端点失效时,没有可靠的方法来通知。那么,如何判断在添加新端点之前是否应该删除旧端点?
如何阻止用户通过重复 subscription/unsubscription 向我的数据库中填充端点来有效地发动拒绝服务攻击?
这更像是个玩笑(我显然可以限制给定用户的总端点),但我看到的问题是,当需要发送通知时,我会用数百个通知来发送通知服务对于无效端点。
我希望我的服务器上的订阅逻辑是:
- 检查我们是否已经为此 user/device 组合保存了端点
- 如果没有添加,如果有,更新
问题是我不知道如何可靠地执行 #1。
I will just add a new endpoint to the database for each device the user subscribes with
最好的方法是 table 像这样:
endpoint | user_id
- 在
endpoint
上添加唯一约束(或主键):您不想将同一个浏览器关联到多个用户,因为它是一团糟(如果端点已经存在但它有一个不同的user_id
,只需更新与之关联的user_id
) user_id
是指向您的用户的外键 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).
是的,不幸的是推送API有a wild unsubscription mechanism,你必须处理它。
端点可能会过期或无效(甚至是恶意的,如 android.chromlum.info
)。当您尝试从您的应用程序服务器发送推送消息时,您需要检测故障(使用 HTTP 状态代码、超时等)。然后,对于某种故障(永久性故障,如过期),您需要删除端点。
What's to stop a user from effectively mounting a denial of service attack by filling my db with endpoints through repeated subscription/unsubscription?
如上所述,您需要正确删除无效端点,一旦您意识到它们已过期或无效。基本上他们最多会产生一个无效请求。此外,如果您的吞吐量很高,您的服务器只需几秒钟就可以向数千个端点发出请求。
我的建议是基于我在开发时所做的大量实验和思考 Pushpad。