建立 CPID

在与 DPA 通信时,GTAF 使用用户密钥来标识订阅者。有权访问用户 MSISDN 的应用可以使用该 MSISDN 作为 user_key。另一方面,无法访问 MSISDN 的应用需要在不发现用户 MSISDN 的情况下建立运营商方案标识符 (CPID)。下面将介绍建立 CPID 的机制。

CPID 通话流程

图 2:用于建立 CPID 的调用流程。

  1. UE 中的 Google 应用使用 Google 内部 API 从 GTAF 检索 CPID 端点的网址。系统会使用客户端的公共 IP 地址和有效 SIM 卡的 MCC+MNC 来识别运营商。对于 MVNO,Google 将使用 SPNGID1 来确定 MVNO
  2. 客户端向 CPID 端点发出 HTTP GET 请求。运营商可以支持通过 HTTPS 发送请求。
  3. 运营商可以使用其深度数据包检测功能来识别请求,并将用户的电话号码作为 HTTP 标头注入到请求中。
  4. CPID 端点接收请求,构建 CPID,并向 UE 返回 CPID,同时返回一个存留时间 (TTL),用于指示 UE 可以使用此 CPID 的时长。

如果运营商愿意,也可以在 CPID 端点网址中使用 IP 地址而不是域名。IP 地址可能位于专用地址空间中,但必须可供运营商网络内的 Google 客户端访问。

运营商应在初始配置流程中向 Google 提供以下信息:

  1. 应用将联系以获取 CPID 的 CPID_网址。必须提供一个 CPID_网址,但运营商可以提供多个网址来提高可用性。
  2. 运营商拥有的 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 中获取。

  1. 当 DPA 从 GTAF 收到有关方案状态或优惠的调用时,可以通过解密 CPID 并提取 MSISDN 来派生 MSISDN。
  2. 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 端点必须根据具体情况返回以下内容:

  1. 如果收到的 CPID 请求是针对不属于运营商网络的用户(例如,属于其他运营商但在由相应 CPID 端点提供服务的网络上漫游的用户),或者针对未选择与 Google 分享流量方案信息的用户,则 CPID 端点必须返回 HTTP 状态代码 403,并将原因设置为 USER_ROAMING、USER_OPT_OUT 或 INELIGIBLE_FOR_SERVICE。
  2. 如果收到的 CPID 请求包含无效的电话号码,则 CPID 端点必须返回 HTTP 400,并显示 INVALID_NUMBER 错误原因。
  3. 如果对 CPID 端点的请求以任何其他方式格式有误,CPID 端点必须返回 HTTP 400,并将 ERROR_CAUSE_UNSPECIFIED 作为原因。
  4. 对于其他错误原因,任何兼容的 HTTP 错误代码都是可以接受的。特别是,HTTP 500 错误非常适合作为 CPID 端点上任何内部故障的错误原因。