developer.apple.com/library/arc…
概述
APNs:Apple Push Notification server苹果推送通知服务, 苹果的APNs允许设备和苹果的推送通知服务器保持连接,支持开发者推送消息给用户设备对应的应用程序。
APNS的推送机制
首先我们看一下苹果官方给出的对ios推送机制的解释。如下图
APNs (Apple Push Ontification service) 服务是远程通知的核心。该服务健全、安全、高效,开发者可以方便的向 iOS tvOS macOS 终端设备推送通知。
当应用在用户设备上运行的时候会在用户设备和 APNS 之间建立一个安全的数据交互连接,应用通过该连接接收通知。
另一半的连接是发送通知的连接,是在你的服务器与 APNS 之间的固定连接,需要在你的开发者帐户中的推送证书。本质上讲,信息提供者是一个服务器,是由你配置及部署的,需要你来写服务端的功能。
服务器的职责
你的服务器在跟 APNS 沟通连接的时候具有以下责任:
- 通过 APNS 接收关于你的app的全球唯一的设备验证码,及其它一些数据
- 根据app功能的需要,决定通知推送的时间
- 建立通知请求,并发送通知请求到 APNs, APNs 再将通知递送到相应的设备
对于每一个通知请求,服务器需要做的:
- 组建一个 JSON 数据,其中包含通知的信息
- 添加 device token和通知信息到一个 HTTP/2 请求中。关于 device token 关于 HTTP/2 参数及回执信息
- 简历一个永久安全的线路 (Security Architecture),发送包含证书的 HTTP/2 请求到 APNs
对于使用多个服务器的
工作图示如下图: 图 6-2 描述了 APNS 为运行您的应用程序的设备启用的虚拟网络类型。为了处理通知负载,您通常会部署多个服务器,每个服务器都有自己与 APNS 的持久且安全的连接
服务质量、存储转发和合并通知
Apple推送通知服务包括一个服务质量(QoS)组件,它执行存储和转发功能。如果apns尝试发送通知,而目标设备离线,apn会将该通知存储一段有限的时间,并在设备重新可用时发送该通知。这个组件只存储每个设备和每个应用程序的最新通知。如果设备离线,发送针对该设备的通知请求将导致前一个请求被丢弃。如果设备长时间处于离线状态,apn中存储的所有通知都会被丢弃。
合并通知
为了允许合并类似的通知,可以在通知请求中包含折叠标识符。正常情况下,当设备处于在线状态时,用户向apn发送的每一个通知请求都会导致通知发送到设备上。然而,当APNs -collapse-id键出现在你的HTTP/2请求头中时,APNs会合并该键值相同的请求。例如,两次发送相同标题的新闻服务可以为两个请求使用相同的折叠标识符值。然后apn将这两个请求合并成一个通知发送给设备。“apns-collapse-id”键的详细说明请参见表Table 8-2.
安全结构
APNs 采用双层信任机制:连接信任
和 device token 信任
APNs 使用两个信任级别强制执行端到端加密验证和身份验证:连接信任和设备令牌信任。
连接信任
工作在服务器与 APNs 之间 | APNs 与设备之间
服务器与APNs之间的信任确保服务器与 APNs 之间的连接是安全的,你需要根据本节中提到的信息,按步骤确保服务器与 APNs 之间的安全连接
APNs与设备之间的信任确保只有验证的设备才能连接 APNs 收到通知,APNs 自动确保与设备之间的连接是安全正确的。
服务器与 APNs 通信的时候,必须实现 验证证书
(基于token的验证)或者 SSL 证书
(基于证书的验证)。你在[开发者帐户]中需要实现这两种验证方式的任意一种,帮助在这。可以查看这里服务器与apns连接信任来确定你需要选择哪种验证方式。
device token 是一个不透明的 NSData
,包含一个设备上的一个应用的唯一标识。只有 APNs 能解密并查看 device token 中的内容。每个应用在向 APNs 发送远程推送注册请求的时候都会收到自己的 唯一的 device token,然后必须把 device token 转发给你app的服务器(详见 配置推送支持)。服务器在发送通知到相应的设备时,必须包含对应的 device token。APNs 通过 device token 来确保通知发送到对应设备的对应app中。
APNs 发行新 device token 的原因有:
- 用户安装你的app到新设备上
- 用户通过备份恢复设备
- 用户重装系统后
- 其它系统层面的事件
所以,app在启动的时候必须请求 device token,参阅 APNs 到设备之间的连接信任 和 device token,看代码实例详见 推送注册请求
注意:为了保护用户隐私,不要用 device token 来标识用户
服务器与 APNs 之间的信任
服务器与APNs之间有两种方式实现连接信任
基于 Token 的服务器与 APNs 之间的信任 服务器可以根据 基于HTTP/2 的API 用JSON web tokens (JWT) 来实现与 APNs 之间的连接信任。这这个模式下,你需要提供一个公共密钥给 Apple。服务器需要用该密钥来生成并添加到 JWT 服务器验证 token。 服务器发出的每个推送请求必须包含该 token。
你就能用简单的基于token的连接,来实现在你开发者帐户中的所有应用的推送请求。
服务器向 APNs 发出的每个推送请求,都会收到 APNs 的 HTTP/2 反馈。
基于证书的服务器与 APNs 之间的信任 服务器也可以通过唯一的证书来实现连接信任。服务器证书可以从开发者帐户中获取到即推送证书,基于你 app 的唯一的证书。然后就可以使用证书来实现推送请求了。
重要 为实现与 APNs 之间基于 HTTP/2的 SSL 连接,你的服务器中必须包含 GeoTrust Gloabl CA 作为根证书。如果你的服务器运行的是 macOS,这个根证书在 keychain 中。其它系统的服务器则就个人情况来安装。你可以从 GeoTrust Root Certificates 网站下载,
基于 Token 的服务器与 APNs 之间的信任
Apple Push Notification Authentication Key (Sandbox & Production) 你需要在你的开发者帐户中进行配置,具体操作看 生成唯一的服务器Token\
这个证书有以下特性:
-
一个证书可以用于向所有包含在帐户下的 app 发送推送。同样可用于 voice over-Internet Protocol(VoIP)。即使在你的app处于后台运行时,APNs 也会向app发送这个证书。详情参见APNs 服务器证书,在开发中的能耗指导查看关于Voice Over IP(VoIP)最好的应用的说明
-
发送推送请求时,必须在基于 JWT 连接中包含该证书
-
认证证书永不失效,但你可以随时通过开发者帐户重新获取,重新获取后旧的证书将不能再使用
下图为: 用 HTTP/2 在服务器与 APNs 之间建立信任连接,用 JWT 向 APNs 发送推送请求
如图所示,工作流程是这样的:
- 服务器向 APNs 请求基于 TLS(transport layer security)的安全连接请求
- APNs 向服务器发送认证证书,到这里,服务器与 APNs 之间的连接已经建立,此时可以发送推送请求
- 服务器需要发送的每个推送请求必须包含 JWT 认证 token
- APNs 向服务器发送 HTTP/2 回执 参见HTTP/2
基于证书的服务器与 APNs 之间的信任
基于证书的服务器连接只支持特定的某一个应用。证书需要在你的服务器上根据你的应用 bundle 提前生成,具体参见 生成一个唯一的通往APNs 的 SSL 连接证书。根据你生成的证书的不同,信任的连接也可以推送一些与你app相关的一些东西,如 apple watch 的并发和 VoIP (voice-over-Internet Protocol)。APNs 会传送推送这些,即使设备仅在后台运行。查阅与 APNs 沟通来获取更多知识,在开发中的能耗指导查看关于Voice Over IP(VoIP)最好的应用的说明。
在基于证书的信任连接中,APNs 会持有一个废止的证书列表,如果服务器的证书在这个列表中,APNs 会废止与服务器的信任连接(也就是说 APNs 会拒绝服务器的请求)
该连接方式的过程是这样的:
- 服务器向 APNs 发出 TLS 连接请求
- APNs 把证书发给服务器
- 服务器需要把你之前从[开发者帐户]中生成的证书发给 APNs,具体参见生成一个唯一的通往APNs 的 SSL 连接证书
- APNs 验证服务器提供的证书是否正确,如果正确,则确定服务器与 APNs 的信任连接。此时服务器可以向 APNs 发送推送请求了。
APNs 与设备之间的连接与 Device Tokens
APNs 与每个设备之间的连接是自动建立的,这个过程中,不需要你的 app 做什么。
每个设备都有一个加密的证书和私有密钥,在设备激活的时候生成,并保存在设备的 keychain 中,在设备激活的时候,APNs 根据设备的证书和密钥验证并授权与设备之间的连接。
过程是这样的:
- 设备向 APNs 发送 TLS 连接请求,信任连接设置开始
- APNs 回执 APNs 证书到设备上
- 设备操作系统验证接收到的 APNs 证书,并向 APNs 发送自己的设备证书
- APNs 验证设备发来证书,如果正确,信任连接建立
当设备与 APNs 之间的信任连接建立之后,此时设备可以向 APNs 申请特定 app 的 device-token,具体参阅 配置远程推送支持 的注册接收远程推送
章节。
在收到 device token 之后,app 必须向其服务器发送接收到的 device token。因为服务器之后向 APNs 发送推送请求时需要用到 device token,代码请参阅 配置远程推送支持
设备激活申请 device token,和 APNs 新生成一个 device token 的过程是一样的,如图:
过程:
- app 向 APNs 申请远程推送请求,如果设备已经注册了远程推送请求,并且特定 app 的 device token 并没有变化,则 APNs 会返回已经存在的 device token 到设备上,跳转到步骤4
- 当一个新的设备需要注册推送请求时,APNs 根据接收到的设备证书来生成一个 device token,并回执给设备
- 设备系统把接收到的 device token 传给 app 并调用 AppDelegate 方法
application:didRegisterForRemoteNotificationWithDeviceToken:
- 设备接收到 device token 之后,需要把它按二进制或十六进制的格式发给你的服务器,服务器才能用该 device token 来发送推送请求
重要
APNs 提供的 device token 的长度不定,不要强行解码其大小
当服务器向 APNs 发送推送请求时,请求中包含中标识唯一设备唯一 app 的 device token,这个过程就是下图中 Token, Payload
过程。APNs 解密 device token 确保推送请求的目标。如果请求的发送者和接收者都合法,APNs 向设备发送请求的推送信息。
在设备接收到 APNs 发来的推送之后,操作系统会把通知递送给相应的 app。
参考: iOS远程推送--APNs详解