通知那些事儿(四):Apple Push Notification Service

本文译自《Apple Push Notification Service》

Apple Push Notification service(APNs)是远程通知的核心。它是一个高效率传播信息给iOS(间接地传送给watchOS)、tvOS和OS X设备的机器人。每个设备都会与APNs建立一个可信任、加密的IP连接,设备能够通过这个长连接接受通知。如果一个通知在应用没有运行的时候到来,那么设备便会通知用户,应用有最新的数据来了。

你的服务器需要为用户生成远程通知,这个服务器也就是常说的provider,它的作用就是从用户那里收集数据并且决定需要什么时候给用户发送通知。provider会生成每个通知的payload,然后将payload添加到一个HTTP/2请求,该请求将会在一个使用HTTP/2多路复用协议的安全可靠的长连接下发送给APNs。APNs在收到这个请求后,则会将通知payload发送给用户设备上的应用。

关于更多发送给APNs请求的组成或者响应,可以参见APNs Provider API

远程通知的传播路径

Apple Push Notification service为你的应用从你的服务器到每个用户设备的通知提供传播和路由功能。下图显示了每条通知的传播路径。当你的服务器决定要发送一个通知,你需要将通知和device token发送给APNs服务器。APNs服务器会为通知到达正确的用户设备寻找路由,最后则由操作系统将通知分发给你的客户端。

图1:Provider到客户端的远程通知

图1

provider到APNs的device token类似于手机号码。它包含了你的客户端应用所在的设备是否开启了APNs服务。APNs用它来验证通知的路由。device token是由你的客户端在注册远程通知后获得并提供给服务器的。

通知的payload是一个包含你想要发送给设备数据的JSON字典。通知的payload包含了你想要如何提醒用户的方式,比如提醒框、角标或提示音。它也可以包含自定义的数据。

图2揭示了更多关于虚拟网络APNs在众多服务器与设备使推送成为可能的真实描述。在APNs中面向设备和面向服务器两端都拥有多个网络连接点。在面向服务器一端,被称为网关。典型的情景是有很多provider,每个provider通过网关维持与APNs一个或多个安全的长连接。并且通过APNs给那些安装它们客户端应用的用户发送通知。

图二:从多服务器到多设备的通知推送

更多关于如何获取device token,请参考Token Generation and Dispersal

服务质量

Apple Push Notification service包含一个执行储存并转发功能的默认的服务质量(QoS)质量组件。如果APNs在设备离线的时候尝试分发通知,通知会在一个限定的时间段内保留,一旦发现设备可达时就会发送保留的通知。针对某个应用只有一条最新的通知会被保留。如果在设备离线的时候,有多条通知发送给用户。那么最新的通知会覆盖之前的通知。这种只保留最新通知的做法被称为聚合通知(coalescing notifications)。

如果如果设备长时间离线,那么被保留的任何通知都会被废弃。

安全架构

为了确保通信安全,APNs在provider和设备间控制入口时使用了两个不同可信认证:连接认证与令牌认证(connnection trust and token trust)。

连接认证会确认在APNs只与那些通过Apple同意发送通知的provider才能建立连接。APNs同时在设备上通过连接认证以确保设备的合法性。在设备上的连接认证是APNs自动化处理的,但是你要确保你的provider与APNs之间的连接认证是否存在。

令牌认证确保了你的通知在合法的起点与终点之间的路由选择。令牌认证涉及到device token的利用,device token是一个为特定设备上的特定应用而分配的一个无意义的标识符。每个应用在注册APNs后都会得到一个唯一的token,而且必须将这个token发送给provider。此后,provider发送的每个通知都需要带上token。提供token确保了通知只会发送到那些针对”应用/设备”的目标用户。

注:device token并不可以用来作为区分一台设备的唯一ID,因为它在更新操作系统之后会改变。所以,应用在其改变后及时告知provider

APNs也需要必要的证书,CA证书和密钥(私钥和公钥)用来验证验证连接与区分provider和设备。

Provider-to-APNs连接认证

每个provider都需要一个provider证书以及密钥,它们用来校验与APNs的连接。provider证书由Apple提供,用来作为识别provider提供的topic(topic是与你的应用相关联的bundle ID)。

通过TLS点对点的认证,provider与APNs建立连接认证。在TLS连接初始化之后,你会从APNs得到一个服务器证书用来在你的这端进行验证。然后你需要将你的证书发送给APNs,这个用来APNs端验证。当这些处理完之后,一个安全的TLS连接就建立了。APNs此时会认为这个连接是一个有合法的provider建立的。

图三:APNs与`provider`建立连接过程

分发给某一应用通知的这个HTTP/2 provider连接是有效的,并且通过在证书中的topic(bundle ID)来区分。根据你如何配置和规定你的APNs的SSL证书,该连接在分发远程通知给关联到Apple Watch或者后台VoIP服务的主应用也是有效的。更多细节可参考APNs Provider API。APNs也会维护一个证书废弃列表。如果provider证书在这个列表上,APNs会取消provider的认证(也就是,拒绝建立连接)。

APNs-to-Device连接认证

每个设备都有一个设备证书和私钥,用来认证设备与APNs之间的连接。设备会在设备激活时获取它的证书及密钥,并存储在钥匙串中。

你无需为APNs和设备间的连接建立做任何事。APNs会根据点对点的认证建立一个可区分的连接。在这个过程中,设备初始化一个与APNs的TLS连接,APNs会返回一个服务器证书。设备验证该证书后,发送一个设备证书给APNs。

图四:APNs与设备建立建立

生成token与传播

一个应用要能够接受远程通知必须要通过系统注册通知。系统在接收到注册请求后,会将该请求转发给APNs。APNs利用设备证书里的信息会生成一个唯一的device token给这个应用。然后将这个token利用一个token key加密并返回给设备。系统从APNs获得并传递给应用的device token是个NSData对象。在收到这个token后,你的应用需要将它以二进制或十六进制的形式转发给你的服务器。因为你的服务器如果没有这个token,是不能发送通知的。

图五:管理device token

重要:APNs device token是长度可变的,所以不要硬编码写死它们长度。

下图说明了token的生成与传播顺序:

图六:device token的分享    

Token认证

你的服务器发送的每个通知都必须要带上device token,因为它关联了你打算要发送到的设备。APNs会利用token key将你发送来的device token解密,以便用来验证通知的源头—也就是,你的provider。APNs利用在device token里包含device ID来区分目标设备。然后将通知发送到目标设备,如下图:

图七:利用device token区分设备