在与 DPA 通信时,GTAF 使用用户密钥来标识订阅者。有权访问用户 MSISDN 的应用可以使用该 MSISDN 作为 user_key。另一方面,无法访问 MSISDN 的应用需要在不发现用户 MSISDN 的情况下建立运营商方案标识符 (CPID)。下面将介绍建立 CPID 的机制。
CPID 通话流程
图 2:用于建立 CPID 的调用流程。
- UE 中的 Google 应用使用 Google 内部 API 从 GTAF 检索 CPID 端点的网址。系统会使用客户端的公共 IP 地址和有效 SIM 卡的 MCC+MNC 来识别运营商。对于 MVNO,Google 将使用 SPN 和 GID1 来确定 MVNO
- 客户端向 CPID 端点发出 HTTP GET 请求。运营商可以支持通过 HTTPS 发送请求。
- 运营商可以使用其深度数据包检测功能来识别请求,并将用户的电话号码作为 HTTP 标头注入到请求中。
- CPID 端点接收请求,构建 CPID,并向 UE 返回 CPID,同时返回一个存留时间 (TTL),用于指示 UE 可以使用此 CPID 的时长。
如果运营商愿意,也可以在 CPID 端点网址中使用 IP 地址而不是域名。IP 地址可能位于专用地址空间中,但必须可供运营商网络内的 Google 客户端访问。
运营商应在初始配置流程中向 Google 提供以下信息:
- 应用将联系以获取 CPID 的 CPID_网址。必须提供一个 CPID_网址,但运营商可以提供多个网址来提高可用性。
- 运营商拥有的 IP 前缀列表,以及运营商希望映射到所提供的 CPID_网址 的移动设备国家/地区代码 (MCC) 和移动网络代码 (MNC)。如果运营商使用 SPN 或 GID1 来区分其网络中的 MVNO,则运营商还应提供此信息。 Google 将使用此信息将客户端与相应的 CPID 端点进行匹配,如图 2 的第 1 步所示。
请求的格式为:
GET CPID_URL
出于旧版原因,CPID 端点应能够支持如下请求:
GET CPID_URL?app={app_id}
CPID 端点可以在生成 CPID 时忽略 {app_id}
网址参数。但是,它必须能够处理包含该参数的请求。
对 CPID 端点的请求可以包含 Accept-Language
标头。如果包含此标头,则 DPA 使用移动数据流量共享 API 发送的更新中的人类可读字符串必须使用 CPID 请求中提供的设置。
每次客户端发出 GET CPID_网址 请求时,都必须收到新的 CPID。如果 CPID 创建成功,则 CPID 端点必须返回 200 OK 响应。响应正文必须包含一个 CPIDResponse 实例。
{
"cpid": "<CPID_string>",
"ttlSeconds": 2592000
}
即使订阅者随后请求了其他 CPID,返回的 CPID 也必须在 ttlSeconds 秒内有效。Google 建议使用 30 天的 TTL 值,但为了获得最佳用户体验,该值不得低于 14 天。在后续对 DPA 的调用中,GTAF 将根据 RFC2396 对 CPID 进行编码。
CPID 生成
CPID 端点创建 CPID 的推荐方式是:
CPID_string = Base64(AES(MSISDN + TimeStamp + language, secret))
CPID 端点会连接 MSISDN、客户端在 Accept-Language 标头中发送的语言和高分辨率时间戳,然后使用 secret
密钥通过 AES 对其进行加密。时间戳应与 CPID 过期时间相对应。加密后的输出采用 Base64 编码。此外,当 CPID 用于网址中时,必须进行网址编码,以处理 Base64 中使用的特殊字符 (/+=)。特别是当 GTAF 调用 DPA 或 DPA 调用移动数据流量共享 API 时,CPID 必须进行网址编码。
根据特定运营商的情况,实现 CPID 端点可能并非易事。经常遇到的一个特殊挑战是在 CPID 端点获取 MSISDN。我们很高兴能分享在运营商初始配置方面学到的经验。如果您遇到任何问题,请与我们联系。
CPID 存储空间
使用上述机制生成的 CPID 不必存储到数据库中。处理向 DPA 发出的调用所需的相关信息可以从 CPID 中获取。
- 当 DPA 从 GTAF 收到有关方案状态或优惠的调用时,可以通过解密 CPID 并提取 MSISDN 来派生 MSISDN。
- CPID 的到期时间可以通过解密 CPID,然后提取到期时间戳来得出。
可用性和容量要求
如果客户端无法检索 CPID,则无法访问移动数据流量套餐 API 中的任何信息。因此,运营商应采取必要措施来确保 CPID 端点的可用性。此类措施包括:拥有多个 CPID 端点和 DPI 功能实例,为这两个功能提供物理、站点和网络冗余,并确保系统资源和容量充足。此外,CPID 端点以及注入标头的 DPI 函数必须具有足够的容量来处理请求 CPID 的所有 Google 客户端的负载。CPID 端点可以在 ttlSeconds
字段中使用更大的值来降低生成 CPID 的频率。
错误情形
如果发生错误,CPID 端点必须返回 HTTP 错误,且响应正文必须包含 ErrorResponse 的实例。良好的错误消息应包含有助于调试错误原因的信息。例如,如果 CPID 已过期,提供 CPID 生成时间和过期时间有助于我们确认 CPID 端点是否按预期运行。
{
"errorMessage": "<error message>",
"cause": "USER_ROAMING"
}
CPID 端点必须根据具体情况返回以下内容:
- 如果收到的 CPID 请求是针对不属于运营商网络的用户(例如,属于其他运营商但在由相应 CPID 端点提供服务的网络上漫游的用户),或者针对未选择与 Google 分享流量方案信息的用户,则 CPID 端点必须返回 HTTP 状态代码 403,并将原因设置为 USER_ROAMING、USER_OPT_OUT 或 INELIGIBLE_FOR_SERVICE。
- 如果收到的 CPID 请求包含无效的电话号码,则 CPID 端点必须返回 HTTP 400,并显示 INVALID_NUMBER 错误原因。
- 如果对 CPID 端点的请求以任何其他方式格式有误,CPID 端点必须返回 HTTP 400,并将 ERROR_CAUSE_UNSPECIFIED 作为原因。
- 对于其他错误原因,任何兼容的 HTTP 错误代码都是可以接受的。特别是,HTTP 500 错误非常适合作为 CPID 端点上任何内部故障的错误原因。