规范化请求

规范化请求定义了用户在向 Cloud Storage 发送经 V4 签名身份验证的请求(例如签名网址)时必须包含的请求元素。

概览

规范化请求是一个字符串,表示向 Cloud Storage 发出的特定 HTTP 请求。您可以将规范化请求和加密密钥(如 RSA 密钥)一起使用,以创建签名,然后将其作为身份验证信息包含在实际请求中。

规范化请求包括 HTTP 动词、查询字符串参数、应在实际请求中使用的标头,以及要请求的对象、存储桶或其他资源等信息。

规范化请求可确保当 Cloud Storage 收到该请求时,它计算的签名与您计算的签名相同。如果您的版本与 Cloud Storage 计算的版本不匹配,请求将失败。

结构

规范化请求具有以下结构,包括在每个元素之间使用换行符:

HTTP_VERB
PATH_TO_RESOURCE
CANONICAL_QUERY_STRING
CANONICAL_HEADERS

SIGNED_HEADERS
PAYLOAD

HTTP 动词

签名请求可以使用以下 HTTP 动词,这些动词必须随规范化请求一起指定:

  • DELETE
  • GET
  • HEAD
  • POST1
  • PUT

1 签名网址只能用于启动可续传上传的 POST 请求。如需了解详情,请参阅将签名网址与可续传上传结合使用

资源路径

规范化请求包括指向要应用该请求的资源的路径。资源路径是位于主机名之后、查询字符串之前的所有内容。

例如,如果 Cloud Storage 网址为 https://storage.googleapis.com/example-bucket/cat-pics/tabby.jpeg,则资源路径为 /example-bucket/cat-pics/tabby.jpeg

如果您使用 https://example-bucket.storage.googleapis.com/cat-pics/tabby.jpeg 等备用 Cloud Storage 网址,则资源路径为 /cat-pics/tabby.jpeg

如需了解可与签名网址一起使用的其他网址端点,请参阅 XML API 请求端点

定义资源路径时,您必须对以下预留字符执行百分号编码?=!#$&'()*+,:;@[]"。网址中使用的所有其他百分号编码也都应包含在资源路径中。

规范化查询字符串

规范化请求会指定每个查询字符串参数,这些参数随后将包含在任何使用相关签名的签名请求中,但 X-Goog-SignatureX-Amz-Signature 查询字符串参数除外。规范化请求中指定的查询字符串称为规范化查询字符串

查询字符串是资源路径末尾问号 (?) 后面的内容。

例如,如果 Cloud Storage 网址为 https://storage.googleapis.com/example-bucket/cat-pics/tabby.jpeg?generation=1360887697105000&userProject=my-project,则查询字符串为 generation=1360887697105000&userProject=my-project

构建规范化查询字符串时,需要注意以下几点:

  • 必须使用按字典顺序排序的代码点值,按名称为查询字符串中的参数排序。

  • 查询字符串中的每个参数必须用 & 分隔。

  • 如果规范化查询字符串为空,则整个规范化请求的这一部分只是一个新行 (\n)。

必需的查询字符串参数

大多数查询字符串参数可根据需要添加,但是如果您打算使用规范化请求来创建签名网址,规范化请求中必须包含以下内容:

  • X-Goog-Algorithm:将用于对网址进行签名的算法。有效值为 GOOG4-RSA-SHA256GOOG4-HMAC-SHA256
  • X-Goog-Credential:将用于对网址进行签名的凭据。这些凭据包含采用以下格式提供的授权方和凭据范围AUTHORIZER%2FCREDENTIAL_SCOPE。授权方可以是服务账号名称HMAC 密钥访问权限 ID
  • X-Goog-Date:可以开始使用相应签名网址的日期和时间(采用 ISO 8601 基本格式 YYYYMMDD'T'HHMMSS'Z')。
  • X-Goog-Expires:签名网址的生命周期(从 X-Goog-Date 开始算起,以秒为单位)。最长到期值为 604800 秒(7 天)。
  • X-Goog-SignedHeaders:以英文分号分隔的标头名称列表,这些标头在规范化请求中定义。它们也称为签名标头。host 必须是这些标头名称之一。

这些查询字符串参数以及 X-Goog-Signature 查询字符串参数(包含对请求进行身份验证的签名)随后必须用于签名网址本身。

规范化标头

规范化请求包括随后必须包含在使用相关签名的签名请求中的所有标头。但是,除了必需标头中所述的标头之外,这些签名请求也可能包含并非在规范化请求中指定的其他标头。规范化请求中指定的标头称为规范化标头

规范化标头可以包含自定义标头以及以 x-goog- 开头的扩展标头

指定规范化标头时,请注意以下几点:

  • 将所有标头名称都设为小写。
  • 使用按字典顺序排序的代码点值,按标头名称对所有标头排序。
  • 使用换行符 (\n) 分隔每个标头。
  • 创建一个标头名称(带有英文逗号分隔的值列表),以消除重复标头名称。确保值之间没有空格,并确保英文逗号分隔列表的顺序与标头在请求中显示的顺序匹配。如需了解详情,请参阅 RFC 7230 第 3.2 节
  • 将折叠空格或换行符(CRLF 或 LF)替换为一个空格。如需详细了解折叠空格,请参阅 RFC 7230 第 3.2.4 节
  • 移除标头名称后面出现的冒号周围的所有空格。

    例如,如果使用了自定义标头 x-goog-acl: private,而没有移除冒号后面的空格,则会返回 403 Forbidden 错误,因为您计算出的请求签名与 Cloud Storage 计算出的签名不匹配。

示例

如果您有下面这样一组标头:

host: storage.googleapis.com
content-type: text/plain
x-goog-meta-reviewer: jane
x-goog-meta-reviewer: john

规范化请求中的规范化标头构造将是:

content-type:text/plain
host:storage.googleapis.com
x-goog-meta-reviewer:jane,john

所需的规范化标头

content-type 等大多数标头均可根据需要添加,但以下标头必须始终在规范标头中进行定义,才能用在已签名的请求中:

  • host:用于访问 Cloud Storage 的 URI。
  • 前缀为 x-goog- 的标头。唯一可以选择作为规范化标头添加的此类标头是 x-goog-content-sha256
  • 前缀为 x-amz- 的标头。唯一可以选择作为规范化标头添加的此类标头是 x-amz-content-sha256

签名标头

规范化标头的名称部分是签名标头。

要创建签名标头列表,请将所有标头名称都转换为小写,按字符代码顺序对其进行排序,并使用英文分号 (;) 分隔各标头名称。

示例

如果您有下面这样一组标头:

host: storage.googleapis.com
content-type: text/plain
x-goog-meta-reviewer: jane
x-goog-meta-reviewer: john

规范化请求中的签名标头构造将是:

content-type;host;x-goog-meta-reviewer

载荷

  • 如果您的规范化请求将用于创建签名网址,则此值应该是字符串 UNSIGNED-PAYLOAD

  • 如果您的规范化请求将在包含 Authorization 标头的请求中使用:

    • 如果您想允许在请求中添加任意载荷,请使用 UNSIGNED-PAYLOAD。 启动可续传上传请求时,我们还建议您使用 UNSIGNED-PAYLOAD。对于可续传上传,系统会忽略所包含的任何 sha256 值。

    • 如果您只想允许特定载荷,则此值应为所需载荷的小写十六进制编码 SHA-256 哈希值。如果要求载荷为空,请使用空字符串作为哈希函数输入项。例如,一个哈希载荷(在此示例中为空载荷)为:

      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

示例

以下是格式正确的规范化请求示例,其换行符显示为实际的新行而非 \n

GET
/example-bucket/tabby.jpeg

host:storage.googleapis.com
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20190301T190859Z

host;x-amz-content-sha256;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

后续步骤