8

我在本 Google 教程的帮助下实现了 Web Push API: https ://developers.google.com/web/fundamentals/getting-started/codelabs/push-notifications/

本教程包含一个方法,可用于将订阅发送到后端服务器:

function updateSubscriptionOnServer(subscription) {
  // TODO: Send subscription to application server
  ...
}

我想将订阅与用户标识符一起存储,以便我可以选择要发送通知的用户。现在我想知道,我必须将订阅的哪一部分存储在数据库中。我的订阅对象如下所示:

{"endpoint":"https://fcm.googleapis.com/fcm/send/...","keys":{"p256dh":"...","auth":"..."}}

我是否应该只创建一个包含整个 JSON 订阅的列 (Id|User_Id|Subscription) 的“订阅”表?什么是最佳实践?JSON 的有效性是无限的吗?如果取消订阅,我可以使用哪个字段来识别订阅?

4

2 回答 2

6

为了允许匿名网络推送用户使用我们的服务,我们提出了对订阅进行哈希处理并将哈希用作后端的主键 ( id ) 的想法。

// pseudo-code
const id = hash(subscription);
https.post(`${SERVER}/subscription/${id}`, subscription).then(...);

正如我正确理解的那样,订阅不会随着时间而改变,因此散列是一个常数。由于每个订阅都是唯一的,因此不会发生冲突,您可以选择适当的散列函数(例如SHA-512)。

然后,您可以在 Service Worker 中重新验证订阅或处理pushsubscriptionchange事件,只要您可以访问原始订阅并重新创建哈希/id。

这应该涵盖大多数情况。但是,当通过 Google 和 Firefox 的推送服务器发送推送通知时,您仍然需要尊重HTTP 401无效订阅的响应代码 ( ) 并将它们从数据库中删除。

有关可用的哈希函数,请参阅Javascript Crypto功能。由 FF 和 Chrome 支持。

于 2017-07-19T15:05:04.740 回答
2

将您的订阅存储在数据库中

如果您使用的是文档数据库,您的数据库应该如下所示:

userId: {type:String, required: true},
endpoint: { type: String, unique: true},
keys: {
 p256dh: {type: String},
 auth: {type: String}
},
userAgent: {type: String}, // optional, just an additional tracking field
deviceId: {type: String} // just additional tracking fields

如果您使用的是关系数据库,则可以将keys零件存储在单独的列中或使用JSON类型列。

要知道的主要事情是webpush.sendNotification(...)接受具有以下接口的对象:

export interface PushSubscription {
    endpoint: string;
    keys: {
        p256dh: string;
        auth: string;
    };
}

这意味着基本上这些是您的数据库需要跟踪订阅的属性。您可以选择为您自己的特定用例添加 userId 和其他人

于 2020-07-13T13:48:07.397 回答