urllib.request 在行为上与 curl 或 httpx 有何不同?在对 Google Container Registry 的请求中获取 401
How does urllib.request differ from curl or httpx in behaviour? Getting a 401 in a request to the Google Container Registry
我目前正在编写一些代码来与 Google Container Registry 上的图像进行交互。我有使用普通 curl
和 httpx
的工作代码。我正在尝试构建一个没有第三方依赖项的包。我的好奇心是围绕一个特定的端点,我从该端点获得了 curl 和 httpx 的成功响应,但是 401 Unauthorized using urllib.request
.
bash 脚本演示了我要实现的目标,如下所示。它从注册表 API 检索访问令牌,然后使用该令牌验证 API 确实是 运行 版本 2,并尝试访问特定的 Docker 图像配置。恐怕为了对此进行测试,您将需要访问私人 GCR 图像和其中一个标签的摘要。
#!/usr/bin/env bash
set -eu
token=$(gcloud auth print-access-token)
image=...
digest=sha256:...
get_token() {
curl -sSL \
-G \
--http1.1 \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--data-urlencode "scope=repository::pull" \
--data-urlencode "service=gcr.io" \
"https://gcr.io/v2/token" | jq -r '.token'
}
echo "---"
echo "Retrieving access token."
access_token=$(get_token ${image})
echo
echo "---"
echo "Testing version 2 capability with access token."
curl -sSL \
--http1.1 \
-o /dev/null \
-w "%{http_code}" \
-H "Authorization: Bearer ${access_token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
https://gcr.io/v2/
echo
echo "---"
echo "Retrieving image configuration with access token."
curl -vL \
--http1.1 \
-o /dev/null \
-w "%{http_code}" \
-H "Authorization: Bearer ${access_token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"https://gcr.io/v2/${image}/blobs/${digest}"
我在 httpx
中另外创建了 two Jupyter notebooks demonstrating my solutions 并裸露了 urllib.request
。 httpx 可以完美运行,而 urllib 以某种方式在图像配置请求上失败。我 运行 想找出不同之处。如果您自己 运行 笔记本,您会看到被调用的 URL 包含一个令牌作为查询参数(这是安全问题吗?)。当我打开 link 时,我实际上可以自己成功下载数据。也许 urllib 仍然通过 Bearer 令牌传递授权 header,使最后一次调用失败并显示 401 Unauthorized?
非常感谢任何见解。
我做了一些调查,我认为不同之处在于最后一次调用 "https://gcr.io/v2/${image}/blobs/${digest}"
实际上包含重定向。检查 curl
和 httpx
调用显示,在第二个重定向请求中,两者都不包含 Authorization
header,而在我设置 urllib.request
在笔记本中,这个 header 总是包含在内。这导致 401 有点奇怪,但现在我知道如何解决它了。
编辑:我现在可以通过构建一个 urllib.request.Request
实例来确认,与链接的笔记本不同,使用请求的 add_unredirected_header
方法添加授权 header,一切都按预期进行.
我目前正在编写一些代码来与 Google Container Registry 上的图像进行交互。我有使用普通 curl
和 httpx
的工作代码。我正在尝试构建一个没有第三方依赖项的包。我的好奇心是围绕一个特定的端点,我从该端点获得了 curl 和 httpx 的成功响应,但是 401 Unauthorized using urllib.request
.
bash 脚本演示了我要实现的目标,如下所示。它从注册表 API 检索访问令牌,然后使用该令牌验证 API 确实是 运行 版本 2,并尝试访问特定的 Docker 图像配置。恐怕为了对此进行测试,您将需要访问私人 GCR 图像和其中一个标签的摘要。
#!/usr/bin/env bash
set -eu
token=$(gcloud auth print-access-token)
image=...
digest=sha256:...
get_token() {
curl -sSL \
-G \
--http1.1 \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--data-urlencode "scope=repository::pull" \
--data-urlencode "service=gcr.io" \
"https://gcr.io/v2/token" | jq -r '.token'
}
echo "---"
echo "Retrieving access token."
access_token=$(get_token ${image})
echo
echo "---"
echo "Testing version 2 capability with access token."
curl -sSL \
--http1.1 \
-o /dev/null \
-w "%{http_code}" \
-H "Authorization: Bearer ${access_token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
https://gcr.io/v2/
echo
echo "---"
echo "Retrieving image configuration with access token."
curl -vL \
--http1.1 \
-o /dev/null \
-w "%{http_code}" \
-H "Authorization: Bearer ${access_token}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"https://gcr.io/v2/${image}/blobs/${digest}"
我在 httpx
中另外创建了 two Jupyter notebooks demonstrating my solutions 并裸露了 urllib.request
。 httpx 可以完美运行,而 urllib 以某种方式在图像配置请求上失败。我 运行 想找出不同之处。如果您自己 运行 笔记本,您会看到被调用的 URL 包含一个令牌作为查询参数(这是安全问题吗?)。当我打开 link 时,我实际上可以自己成功下载数据。也许 urllib 仍然通过 Bearer 令牌传递授权 header,使最后一次调用失败并显示 401 Unauthorized?
非常感谢任何见解。
我做了一些调查,我认为不同之处在于最后一次调用 "https://gcr.io/v2/${image}/blobs/${digest}"
实际上包含重定向。检查 curl
和 httpx
调用显示,在第二个重定向请求中,两者都不包含 Authorization
header,而在我设置 urllib.request
在笔记本中,这个 header 总是包含在内。这导致 401 有点奇怪,但现在我知道如何解决它了。
编辑:我现在可以通过构建一个 urllib.request.Request
实例来确认,与链接的笔记本不同,使用请求的 add_unredirected_header
方法添加授权 header,一切都按预期进行.