我无法使用您描述的设置重现您看到的错误,但我可以通过额外的日志记录向您展示什么对我来说正常工作,您可以将其与您的失败案例进行比较以尝试查看是什么不同的。
我在Django shell(python manage.py shell
我们的工作理论是 boto 使用错误的时区来计算签名 API 请求的时间戳,所以让我们启用一些涵盖该区域的详细boto3 日志记录:
import boto3
boto3.set_stream_logger('botocore.auth') # log the signature logic
boto3.set_stream_logger('botocore.endpoint') # log the API request
# boto3.set_stream_logger('botocore.parsers') # log the API response (if you want)
现在尝试发送消息:
from django.core.mail import send_mail
send_mail("Test", "testing", None, ['success@simulator.amazonses.com'])
您应该会看到如下所示的日志输出:
2019-03-19 20:48:32,321 botocore.endpoint [DEBUG] Setting email timeout as (60, 60)
2019-03-19 20:48:32,580 botocore.endpoint [DEBUG] Making request for OperationModel(name=SendRawEmail) with params: {'body': {'Action': u'SendRawEmail', 'Version': u'2010-12-01', 'RawMessage.Data': [base64 message omitted]'}, 'url': u'https://email.us-east-1.amazonaws.com/', 'headers': {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'User-Agent': 'Boto3/1.9.117 Python/2.7.15 Darwin/18.2.0 Botocore/1.12.117 django-anymail/3.0-amazon-ses'}, 'context': {'auth_type': None, 'client_region': 'us-east-1', 'has_streaming_input': False, 'client_config': <botocore.config.Config object at 0x10dadd1d0>}, 'query_string': '', 'url_path': '/', 'method': u'POST'}
2019-03-19 20:48:32,581 botocore.auth [DEBUG] Calculating signature using v4 auth.
2019-03-19 20:48:32,581 botocore.auth [DEBUG] CanonicalRequest:
POST
/
content-type:application/x-www-form-urlencoded; charset=utf-8
host:email.us-east-1.amazonaws.com
x-amz-date:20190320T064832Z
content-type;host;x-amz-date
[redacted]
2019-03-19 20:48:32,582 botocore.auth [DEBUG] StringToSign:
AWS4-HMAC-SHA256
20190320T064832Z
20190320/us-east-1/ses/aws4_request
[redacted]
2019-03-19 20:48:32,582 botocore.auth [DEBUG] Signature:
[redacted]
2019-03-19 20:48:32,582 botocore.endpoint [DEBUG] Sending http request: <AWSPreparedRequest stream_output=False, method=POST, url=https://email.us-east-1.amazonaws.com/, headers={'Content-Length': '437', 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'Authorization': 'AWS4-HMAC-SHA256 Credential=[key id redacted]/20190320/us-east-1/ses/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=[redacted]', 'X-Amz-Date': '20190320T064832Z', 'User-Agent': 'Boto3/1.9.117 Python/2.7.15 Darwin/18.2.0 Botocore/1.12.117 django-anymail/3.0-amazon-ses'}>
这里的重要部分是日期:
2019-03-19 20:48:32,581 botocore.auth [DEBUG] CanonicalRequest:
...
x-amz-date:20190320T064832Z
2019-03-19 20:48:32,582 botocore.auth [DEBUG] StringToSign:
...
20190320T064832Z
20190320/...
2019-03-19 20:48:32,582 botocore.endpoint [DEBUG] Sending http request: <AWSPreparedRequest ...
headers={
'Authorization': '.../20190320/...',
'X-Amz-Date': '20190320T064832Z', ...}>
请注意,签名计算均基于 UTC 日期 (2019-03-20),而不是我的 Django 时区 (2019-03-19) 中的当前本地日期。
所以看起来 boto3确实使用 UTC 进行签名计算,尽管 Django/环境时区。事实上,发送对我有用,没有错误。
所以问题是,当你看到问题时有什么不同?
- CanonicalRequest 中的 x-amz-date 是什么?
- 实际上,这是您发送消息时的实际 UTC 日期时间吗?(如果没有,您的 Docker 容器中的时钟可能已经过时了。)
- 相同的日期是否再次正确出现在 StringToSign 中,作为完整的时间戳和截断的日期?
- 它是否再次出现在 AWSPreparedRequest 标头
Authorization
中X-Amz-Date
?(如果你看到一个Date
标题而不是X-Amz-Date
,那也会很有趣。)
希望这可以帮助您更接近解决方案,或者至少找出重现问题所必需的细节。