Я не могу воспроизвести ошибку, которую вы видите, с описанными вами настройками, но я могу показать вам, что работает правильно для меня, с помощью дополнительной регистрации, и вы можете сравнить это с вашим неудачным случаем, чтобы попробовать чтобы увидеть, что отличается.
Я запустил этот код в оболочке Django (python manage.py shell
) просто для удобства, но вы можете поместить его в режим отладки или в любое другое удобное для вас место.
Наша рабочая теория заключается в том, что boto использует неправильный часовой пояс для вычисления временных отметок при подписании запроса API, поэтому давайте включим некоторые подробные loging 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 / среды. И действительно, отправка у меня работает без ошибок.
Итак, вопрос в том, что отличается, когда вы видите проблему?
- Что такое x-amz-date в CanonicalRequest?
- Фактически это фактическая дата-время UTC при отправке сообщения?
(Если нет, то часы в вашем контейнере Docker могут быть выключены.)
- Отображается ли эта же дата снова правильно в StringToSign, как в виде полной отметки времени, так и в виде усеченной даты?
- И появляется ли он снова в заголовках AWSPreparedRequest,
Authorization
и X-Amz-Date
? (Если вместо X-Amz-Date
вы видите заголовок Date
, это также будет интересно.)
Надеюсь, это поможет вам либо приблизиться к решению, либо хотя бы выяснить, какие детали необходимы для воспроизведения проблемы.