GCM令牌何时过期,InstanceID是什么?

28

由于GCM不断更新,我搜索到的大多数资源已经过时或不清楚。基本上,我对令牌和ID何时过期感到困惑。(供参考,我正在使用Android工作。)

据我所了解(如有错误请纠正),我的服务器有一个API密钥和一个发件人ID。使用发件人ID,我可以让我的客户端通过在客户端存储的InstanceID请求一个令牌。这里我已经有点困惑了。InstanceID是在我的应用程序上线时分配的吗?它会改变吗?当应用程序升级或被卸载并重新安装(或设备被还原)时呢?调用InstanceID.getInstance时,我总是会检索到相同的InstanceID,还是最终会过期并给我一个新的实例ID?将通过调用getID()检索到的字符串存储有任何价值吗?文档似乎表明,当您调用getID()时,实际上会检索到一个新的InstanceID,因此更加复杂。(供参考,请参见: https://developers.google.com/instance-id/)

使用InstanceID,我的客户端可以从GCM服务器请求令牌,然后将其发送到我的应用程序服务器。我的应用程序服务器存储此令牌,并可以使用此令牌向GCM服务器发送消息,GCM服务器然后将消息发送到设备。我相信设备使用存储的InstanceID来接收这些消息。因此,拥有一个扩展GcmListenerService的类将允许我使用onMessageReceived接收这些消息?我不需要做任何特殊的事情(除了在AndroidManifest中定义它)吗?我不需要实际告诉它使用InstanceID吗?它只是神奇地知道吗?

这些ID和令牌何时过期?它们会过期吗?我将令牌存储为服务器上的字符串,但如果其中一个过期了,我如何知道它们已过期?我始终可以生成新的InstanceID和Token,这似乎很容易,但旧的令牌是否仍然保持活动状态呢?我如何从服务器中清除旧的令牌?在iOS端的APNS中似乎有一种简单的方法可以做到这一点,您可以检索所有过期令牌的列表并从数据库中删除它们。


我也有类似的问题,并在此处发现了一些答案:https://developers.google.com/android/reference/com/google/android/gms/iid/InstanceID - Simon
3个回答

26

我在更新GCM实现时发现自己问了大部分这些问题。经过几天的试验,以下是我的看法。

据我所知(如果我错了,请纠正我),我的服务器有一个API密钥和一个发送者ID。使用发送者ID,我可以让客户端通过在客户端上本地存储的InstanceID请求令牌。

这是正确的。

InstanceID是在我的应用程序上线的那一刻分配的吗?

看起来它是在应用程序启动时分配的,即使设备无法访问互联网。

它会改变吗?当应用程序升级或卸载并重新安装(或设备被还原)时会怎样?通过调用InstanceID.getInstance,我是否总是检索到相同的InstanceID,还是最终会过期并给我一个新的InstanceID?

根据InstanceID文档:

实例 ID 是稳定的,但可能会无效,如果: - 应用程序删除实例 ID - 设备出厂重置 - 用户卸载应用程序 - 用户清除应用程序数据
如果实例 ID 变为无效,则应用程序可以调用 getId() 请求新的实例 ID。
我已经测试了卸载应用程序和清除数据,结果表明上述所有情况都是正确的。
调用 getId() 返回的字符串是否有任何价值?
看起来 API 处理了将其存储在您的应用程序本地存储中的操作。
使用 InstanceID,我的客户端可以从 GCM 服务器请求令牌,然后将其发送到我的应用程序服务器。我的应用程序服务器存储此令牌,并可使用它向 GCM 服务器发送消息,GCM 服务器将消息发送到设备。我认为设备使用存储的 InstanceID 实际接收这些消息。因此,拥有一个扩展 GcmListenerService 的类将允许我使用 onMessageReceived 接收这些消息?我不需要做任何特殊的事情(除了在 AndroidManifest 中定义)?我不必真正告诉它使用 InstanceID?它只是神奇地知道吗?
据我所知,在以前的实现中没有任何InstanceId,而且在这个实现中似乎也没有被明确使用。如果有的话,它将在 GcmReceiverGcmListenerService中调用。
这些ID和令牌何时过期?它们会过期吗?
我已经解决了ID过期的问题,我们可以在Android InstanceID implementation guide中了解有关令牌过期的信息:
Instance ID服务定期启动回调(例如,每6个月),请求您的应用程序刷新其令牌。当发生以下情况时,它还可能会启动回调:
- 存在安全问题;例如,SSL或平台问题。 - 设备信息不再有效;例如,备份和恢复。 - Instance ID服务受到影响。

指南建议创建InstanceIDListenerService的子类并覆盖onTokenRefresh()来处理这些情况。

我将令牌作为字符串存储在服务器上,但如果其中任何一个过期了,我怎么知道它们已经过期了?

实现GCM的指南指出,GCM服务器会向您的服务器响应有关您用于尝试发送推送通知的令牌的某些信息。

我总是可以生成新的InstanceID和令牌,这似乎很容易,但旧的InstanceID和令牌是否仍然有效?

我的测试表明是的。

如何从服务器中清除旧的令牌?在iOS端的APNS中,似乎有一种简单的方法可以做到这一点,您可以检索所有过期令牌的列表,然后从数据库中清除它们。

我仍在研究中,如果我能找到解决方案,我会更新的。


2
根据这个指南(https://developers.google.com/cloud-messaging/registration),可以使用```InstanceID.deleteToken()```和```InstanceID.deleteInstanceID```从GCM服务器中清除旧的令牌和ID。 - degill
1
此外,似乎 ID 处理是在移动设备本身上完成的(因为 deleteInstanceID 和 getID 都可以在主线程上调用,因此不会进行任何网络调用),而令牌处理则连接到 GCM 服务器(https://developers.google.com/android/reference/com/google/android/gms/iid/InstanceID.html)。 - degill
1
没错,我一直在尝试找出如何获取已过期令牌列表,以便从我的服务器中删除它们,避免不必要的膨胀。我将答案标记为正确,因为它非常有帮助,但实际上我也为这个问题找到了解决方案。它并不是特别优雅或安全,但基本上当令牌生成时,我会将其保存在设备和服务器上。然后,当设备上的应用程序启动时,我会将令牌的本地副本发送到服务器,如果它与服务器上的令牌不匹配,则擦除先前的令牌。希望这能帮助到某些人。 - B. Roth
1
@b-roth 只有在设备仍具有相同的 InstanceID 时才能起作用,是吗?因此,对于已重置、删除了应用程序数据或卸载并重新安装了应用程序的设备,您仍然无法删除旧令牌。 - pumpkinpie65
1
@pumpkinpie65 这是正确的,这只是一种假设应用程序不会被重置的解决方案。我们的应用程序为每个设备分配了硬件ID,但如果您卸载并重新安装,则会丢失该ID,因此它将被困在DB中。还有一种解决方法,如果您使用我的先前想法添加了到期日期,它也可以起作用。基本上,当应用程序启动时,它会发送令牌,然后DB存储当前时间。如果经过X段时间并且当前时间未更新,则我们会清除令牌。 - B. Roth
显示剩余2条评论

6
这是我检测数据库中无效令牌的方法:
在向用户/用户列表发送通知时,GCM 中有一个“干运行”选项。当您在发送通知时设置“dry-run”选项时,它不会向客户端发出警报或显示通知,而是返回关于哪些令牌有效(200)和哪些无效的响应。
如果您使用 dry-run 选项向200个用户发送通知,则您将按相同顺序从 GCM 获取响应。

3

什么是Instance ID?

Instance ID为应用程序的每个实例提供唯一的标识符。您可以在Android和iOS应用程序以及Chrome应用程序/扩展中实现Instance ID。

除了为认证提供唯一ID外,Instance ID还可以生成用于其他服务的安全令牌。

主要特点

  • 生成安全令牌
  • 验证应用程序真实性
  • 确认应用程序设备处于活动状态
  • 识别和跟踪应用程序

Instance ID生命周期

  1. 当您的应用程序上线时,Instance ID服务会发出一个InstanceID。此InstanceID由一个公共/私有密钥对支持,其中私钥存储在本地设备上,公钥注册在InstanceID服务中。
  2. 使用getID()方法,您的应用程序可以根据需要请求新的InstanceID。如果您拥有支持您的应用程序的服务器,则可以将其存储在服务器上。
  3. 您的应用程序可以随时使用getToken()方法从Instance ID服务请求令牌。与InstanceID一样,您的应用程序也可以将令牌存储在自己的服务器上。所有颁发给您的应用程序的令牌均属于应用程序的InstanceID。
  4. 令牌是独特且安全的,但在发生安全问题或用户卸载并重新安装设备恢复期间时,您的应用程序或Instance ID服务可能需要刷新令牌。您的应用程序必须实现侦听器以响应Instance ID服务的令牌刷新请求。

什么情况下会使Instance ID无效?

  • 应用程序删除Instance ID
  • 设备恢复出厂设置
  • 用户卸载应用程序
  • 用户清除应用程序数据

如果Instance ID已变为无效状态,则应用程序可以调用getID()请求新的Instance ID。为了证明Instance ID的所有权并允许服务器访问与应用程序相关的数据或服务,请调用getToken(String, String)。

何时刷新令牌?

Instance ID服务定期启动回调(例如,每6个月一次),请求您的应用程序刷新其令牌。当以下情况发生时,它也可能启动回调:

存在安全问题;例如,SSL或平台问题。 设备信息不再有效;例如,备份和还原。 Instance ID服务受到影响。

有关Instance ID的所有信息均可在以下官方链接中找到:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接