gpt4 book ai didi

python - AWS HTTP API - Python 请求与 Dart HTTP 中的请求相同但响应不同

转载 作者:太空宇宙 更新时间:2023-11-03 11:58:48 30 4
gpt4 key购买 nike

我正在尝试在 Flutter 应用程序中使用 AWS DynamoDB,由于缺少适用于 Dart 的官方 AWS SDK,我不得不使用低级 HTTP REST API。

签署 AWS HTTP 请求的方法非常繁琐,但使用 AWS supplied sample作为指导,我能够相对轻松地将 Python 逐行转换为 Dart。最终结果是两组代码生成相同的身份验证签名。

当我真正去发送请求时,我的问题就来了。 Python 按预期工作,但使用 Dart 的 HTTP 包发送 POST 会给出错误

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

我将为您省去用于生成身份验证签名的实际代码,因为可以通过发送相同的硬编码请求来简单地复制问题。请参阅下面的 Python 和 Dart 代码。

注意:一个有效的响应将返回

Signature expired: 20190307T214900Z is now earlier than 20190307T215809Z (20190307T221309Z - 15 min.)

因为请求签名使用当前日期并且仅在 15 分钟内有效。

*****Python 代码*****

import requests

headers = {'Content-Type':'application/json',
'X-Amz-Date':'20190307T214900Z',
'X-Amz-Target':'DynamoDB_20120810.GetItem',
'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320'}

endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/'
request_parameters = '{"TableName": "player-exports","Key": {"exportId": {"S": "HG1T"}}}'

r = requests.post(endpoint, data=request_parameters, headers=headers)

print('Response status: %d\n' % r.status_code)
print('Response body: %s\n' % r.text)

*****DART 代码*****

import 'package:http/http.dart' as http;

void main(List<String> arguments) async {

var headers = {'Content-Type':'application/json',
'X-Amz-Date':'20190307T214900Z',
'X-Amz-Target':'DynamoDB_20120810.GetItem',
'Authorization':'AWS4-HMAC-SHA256 Credential=AKIAJFZWA7QQAQT474EQ/20190307/ap-southeast-2/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=297c5a03c59db6da45bfe2fda6017f89a0a1b2ab6da2bb6e0d838ca40be84320'};

var endpoint = 'https://dynamodb.ap-southeast-2.amazonaws.com/';
var request_parameters = '{"TableName": "player-exports","Key": {"exportId": {"S": "HG1T"}}}';

http.post(endpoint, body: request_parameters, headers: headers).then((response) {
print("Response status: ${response.statusCode}");
print("Response body: ${response.body}");
});
}

端点、 header 和正文实际上是在两组代码之间复制和粘贴的。

Dart HTTP 的工作原理是否有一些我在这里遗漏的细微差别? header 或 request_paramaters 是否发生了一些 map/string/json 转换?

我注意到的一件事是,在 AWS 提供的示例中它指出

For DynamoDB, the request can include any headers, but MUST include "host", "x-amz-date", "x-amz-target", "content-type", and "Authorization". Except for the authorization header, the headers must be included in the canonical_headers and signed_headers values, as noted earlier. Order here is not significant. Python note: The 'host' header is added automatically by the Python 'requests' library.

但是

a) 当我将 'Host':'dynamodb.ap-southeast-2.amazonaws.com' 添加到 Dart 代码中的 header 时,我得到了相同的结果

b) 如果我在 Python 请求返回后查看 r.request.headers,我可以看到它自动添加了一些新 header (Content-Length 等),但“Host”不是其中之一。

知道为什么看似相同的 HTTP 请求适用于 Python 请求而不适用于 Dart HTTP 吗?

最佳答案

好的,现在已经解决了。我的问题在一定程度上是一个巨大的用户错误。我正在使用一个新的 IDE,当我生成我提供的硬编码示例时,我实际上仍在执行以前的文件。愚蠢,愚蠢,愚蠢。

但是……

我能够首先解决导致我提出问题的实际问题。我发现如果在 header 中将内容类型设置为“application/json”,dart HTTP 包会自动附加“;charset=utf-8”。因为此值是 auth 签名的一部分,所以当 AWS 对 header 中的值进行编码以与用户生成的签名进行比较时,它们不匹配。

修复只是为了确保在设置 header 内容类型时,确保手动将其设置为“application/json; charset=utf-8”而不是“application/json”。

事后发现了关于这个“错误”的更多讨论 here .

关于python - AWS HTTP API - Python 请求与 Dart HTTP 中的请求相同但响应不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55053940/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com