使用签名网址。

本页面简要介绍签名网址以及将其用于 Cloud CDN 的说明。拥有签名网址的任何人都会获得限时的资源访问权限,无论该用户是否拥有 Google 账号都是如此。

签名网址提供可用于发出请求的有限权限和时间。签名网址的查询字符串中包含身份验证信息,这样,用户不需要提供凭据也可对资源执行特定操作。 生成签名网址时,您需要指定一个用户或服务账号,且该用户或服务账号具有的权限必须足以发出与该网址相关的请求。

生成签名网址后,拥有该网址的任何人都可以使用该网址,在指定的时间段内执行指定的操作(例如读取对象)。

签名网址还支持可选的 URLPrefix 参数,允许您提供访问具有相同前缀的多个网址的权限。

如果要限制对特定网址前缀的访问权限,请考虑使用签名 Cookie

准备工作

在使用签名网址之前,请执行以下操作:

  • 确保已启用 Cloud CDN;如需了解相关说明,请参阅使用 Cloud CDN。您可以先在后端配置签名网址,然后再启用 Cloud CDN;在启用 Cloud CDN 之前,相关配置不会生效。

  • 如有必要,请更新到 Google Cloud CLI 的最新版本:

    gcloud components update
    

如需查看概览,请参阅签名网址和签名 Cookie

配置签名请求密钥

为签名网址或签名 Cookie 创建密钥需要执行几个步骤,详情请参阅下面几部分内容。

安全注意事项

在下列情况下,Cloud CDN 不会验证请求:

  • 请求未签名。
  • 请求的后端服务或后端存储桶未启用 Cloud CDN。

系统必须始终先在源站验证签名的请求,然后再传送响应。这是因为源站可用于传送签名的和未签名的混合内容,而且客户端可能会直接访问源站。

  • Cloud CDN 不会屏蔽没有 Signature 查询参数或 Cloud-CDN-Cookie HTTP Cookie 的请求。它会拒绝请求参数无效(或格式不正确)的请求。
  • 当您的应用检测到无效签名时,请确保其使用 HTTP 403 (Unauthorized) 响应代码来作出响应。HTTP 403 响应代码不可缓存。
  • 签名请求和未签名请求的响应会单独缓存,因此对有效签名请求的成功响应绝不会用于传送未签名的请求。
  • 如果您的应用向无效请求发送了可缓存的响应代码,则未来的有效请求可能会被错误地拒绝。

对于 Cloud Storage 后端,请务必移除公共访问权限,以便 Cloud Storage 可以拒绝缺少有效签名的请求。

下表总结了这种行为。

请求具有签名 缓存命中 行为
转发到后端源站。
从缓存传送。
验证签名。如果有效,则转发到后端源站。
验证签名。如果有效,则从缓存传送。

创建签名请求密钥

如需启用对 Cloud CDN 签名网址和签名 Cookie 的支持,您可以对启用了 Cloud CDN 的后端服务和/或后端存储分区创建一个或多个密钥。

您可以根据自己的安全需求,为每个后端服务或后端存储桶创建和删除密钥。每个后端最多可以同时配置三个密钥。我们建议您定期轮换密钥,即删除最旧的密钥,然后添加新密钥,并在为网址或 Cookie 签名时使用新密钥。

您可以在多个后端服务和后端存储分区中使用相同的密钥名称,因为各组密钥是彼此独立的。密钥名称最长为 63 个字符。要命名密钥,请使用字符 A-Z、a-z、0-9、_(下划线)、-(连字符)。

创建密钥后,务必妥善保管好密钥,因为只要拥有其中一个密钥,任何人都可以创建 Cloud CDN 接受的签名网址或签名 Cookie,直到该密钥从 Cloud CDN 中删除为止。密钥存储在生成签名网址或签名 Cookie 的计算机上。Cloud CDN 也会存储这些密钥以验证请求签名。

为了确保密钥的机密性,请勿在任何 API 请求的响应中包含密钥值。如果您丢失了某个密钥,则必须创建一个新密钥。

如需创建签名请求密钥,请按照以下步骤操作。

控制台

  1. 在 Google Cloud 控制台中,前往 Cloud CDN 页面。

    转到 Cloud CDN

  2. 点击您要为其添加密钥的来源的名称。
  3. 源站详情页面上,点击修改按钮。
  4. Origin basics(来源基本信息)部分中,点击下一步以打开主机和路径规则部分。
  5. 主机和路径规则部分中,点击下一步以打开缓存性能部分。
  6. 受限内容部分中,选择使用签名网址和签名 Cookie 限制访问权限
  7. 点击添加签名密钥

    1. 为新签名密钥指定一个唯一的名称。
    2. 密钥创建方法部分中,选择自动生成。或者,点击让我输入,然后指定签名键值。

      对于前一个选项,请将自动生成的签名密钥值复制到一个私有文件中,您可以使用该值来创建签名网址

    3. 点击完成

    4. 缓存条目存在时间上限部分,输入一个值,然后选择一个时间单位。

  8. 点击完成

gcloud

gcloud 命令行工具会从您指定的本地文件中读取密钥。密钥文件必须按照如下方式创建:生成强随机 128 位代码,使用 base64 对该代码进行编码,然后将字符 + 替换为 -、将字符 / 替换为 _。如需了解详情,请参阅 RFC 4648。必须确保密钥具有强随机性。在类似 UNIX 的系统上,您可以使用以下命令生成强随机密钥并将密钥存储在密钥文件中:

head -c 16 /dev/urandom | base64 | tr +/ -_ > KEY_FILE_NAME

如需将密钥添加到后端服务,请执行以下操作:

gcloud compute backend-services \
   add-signed-url-key BACKEND_NAME \
   --key-name KEY_NAME \
   --key-file KEY_FILE_NAME

如需将密钥添加到后端存储分区,请执行以下操作:

gcloud compute backend-buckets \
   add-signed-url-key BACKEND_NAME \
   --key-name KEY_NAME \
   --key-file KEY_FILE_NAME

配置 Cloud Storage 权限

如果您使用 Google Cloud Storage,并且限制了可以读取对象的用户,则必须向 Cloud CDN 授予读取对象的权限,方法是将 Cloud CDN 服务账号添加到 Cloud Storage ACL 中。

您无需创建服务账号。当您首次将密钥添加到项目中的后端存储分区时,系统将自动创建服务账号。

在运行以下命令之前,请向项目中的后端存储分区添加至少一个密钥。否则,该命令会失败并显示错误,这是因为您必须先为项目添加一个或多个密钥,系统才会创建 Cloud CDN 缓存填充服务账号。

gcloud storage buckets add-iam-policy-binding gs://BUCKET \
  --member=serviceAccount:service-PROJECT_NUMBER@cloud-cdn-fill.iam.gserviceaccount.com \
  --role=roles/storage.objectViewer

PROJECT_NUMBER 替换为您的项目编号,将 BUCKET 替换为您的存储桶。

Cloud CDN 服务账号 service-PROJECT_NUMBER@cloud-cdn-fill.iam.gserviceaccount.com 不会出现在您项目的服务账号列表中。这是因为 Cloud CDN 服务账号归 Cloud CDN 所有,不属于您的项目。

如需详细了解项目编号,请参阅 Google Cloud 控制台帮助文档中的查找项目 ID 和项目编号

自定义最长缓存时间

无论后端的 Cache-Control 标头如何,Cloud CDN 都会缓存针对签名请求的响应。响应无需重新验证的最长缓存时间由 signed-url-cache-max-age 标志设置,默认设为 1 小时,您可以按照此处所示的方法进行修改。

要设置后端服务或后端存储分区的最长缓存时间,请运行以下命令之一:

gcloud compute backend-services update BACKEND_NAME \
  --signed-url-cache-max-age MAX_AGE
gcloud compute backend-buckets update BACKEND_NAME \
  --signed-url-cache-max-age MAX_AGE

列出签名请求密钥名称

要列出后端服务或后端存储分区上的密钥,请运行以下命令之一:

gcloud compute backend-services describe BACKEND_NAME
gcloud compute backend-buckets describe BACKEND_NAME

删除签名请求密钥

如果采用特定密钥签名的网址不再受到支持,请运行以下某个命令以从后端服务或后端存储分区中删除该密钥:

gcloud compute backend-services \
   delete-signed-url-key BACKEND_NAME --key-name KEY_NAME
gcloud compute backend-buckets \
   delete-signed-url-key BACKEND_NAME --key-name KEY_NAME

为网址签名

最后一步是对网址进行签名并分发网址。您可以使用 gcloud compute sign-url 命令或使用自己编写的代码对网址进行签名。如果您需要大量签名网址,则自定义代码的性能更佳。

创建签名网址

按照以下说明使用 gcloud compute sign-url 命令创建签名网址。此步骤假定您已创建密钥

控制台

您无法使用 Google Cloud 控制台创建签名网址,您可以使用 Google Cloud CLI,也可以使用以下示例编写自定义代码。

gcloud

Google Cloud CLI 包含用于对网址进行签名的命令。该命令可实现编写自己的代码部分所述的算法。

gcloud compute sign-url \
  "URL" \
  --key-name KEY_NAME \
  --key-file KEY_FILE_NAME \
  --expires-in TIME_UNTIL_EXPIRATION \
  [--validate]

该命令会读取 KEY_FILE_NAME 中采用 base64url 编码的密钥值并对其进行解码,然后输出一个签名网址;您可以将该签名网址用于针对指定网址发出的 GETHEAD 请求。

例如:

gcloud compute sign-url \
  "https://example.com/media/video.mp4" \
  --key-name my-test-key \
  --expires-in 30m \
  --key-file sign-url-key-file

URL 必须是包含路径某个组成部分的有效网址。例如,http://example.com 无效,不过 https://example.com/https://example.com/whatever 均为有效网址。

如果指定了可选的 --validate 标志,则此命令会发送包含生成的网址的 HEAD 请求,并输出 HTTP 响应代码。如果签名网址是正确的,则响应代码与您的后端发送的结果代码相同。如果响应代码不相同,请重新检查 KEY_NAME 以及指定的文件的内容,并确保