[英]Amazon SES with Django not in UTC timezone
I'm developing a django project for use in America, specifically the New York timezone and the system is hosted on AWS, with SES sending email. 我正在开发一个在美国使用的django项目,特别是纽约时区,该系统在AWS上托管,SES发送电子邮件。 The email backend is using django-anymail which is a simple wrapper for SES and the system uses
send_mail
from django core. 电子邮件后端使用的是django-anymail ,它是SES的一个简单包装器,系统使用django core的
send_mail
。
To support this I've opted for the following Django settings; 为了支持这一点,我选择了以下Django设置;
EMAIL_BACKEND = "anymail.backends.amazon_ses.EmailBackend"
LANGUAGE_CODE = 'en'
TIME_ZONE = 'America/New_York'
USE_I18N = False
USE_L10N = True
USE_TZ = True
ANYMAIL = {
"AMAZON_SES_CLIENT_PARAMS": {
"region_name": AWS_SES_REGION_NAME,
},
}
With the above settings django calls tzset()
on startup which modifies the system timezone. 通过上述设置,django在启动时调用
tzset()
来修改系统时区。 This then means the timestamp used by botocore
to sign the requests for SES is not UTC, because the following error is received from message sending; 这意味着
botocore
用于签署SES请求的时间戳不是UTC,因为从消息发送中收到以下错误;
An error occurred (ExpiredToken) when calling the SendRawEmail operation: The security token included in the request is expired
调用SendRawEmail操作时发生错误(ExpiredToken):请求中包含的安全令牌已过期
Emails are sent successfully by changing settings to TIME_ZONE = 'UTC'
. 通过将设置更改为
TIME_ZONE = 'UTC'
来成功发送电子邮件。
I can only assume that the requests are being signed in UTC -4 which then hit AWS which is in UTC. 我只能假设这些请求是以UTC-4签署的,然后以UTC格式登录AWS。
How can django run in a specific timezone, but boto operate with UTC timestamps? django如何在特定时区运行,但是boto是否以UTC时间戳运行?
The system is running in a docker container (pre-production); 系统在docker容器中运行(预生产);
LocaleMiddleware
is loaded LocaleMiddleware
已加载 I'm not able to reproduce the error you're seeing with the settings you've described, but I can show you what is working correctly for me with extra logging, and you could compare that to your failing case to try to see what's different. 我无法使用您所描述的设置重现您所看到的错误,但我可以通过额外的日志记录向您展示正常工作的内容,您可以将其与失败案例进行比较,以尝试查看什么是不同。
I ran this code in the Django shell ( python manage.py shell
) just for convenience, but you could put it in a debugging view or anywhere else that works for you. 我在Django shell (
python manage.py shell
)中运行此代码只是为了方便,但您可以将它放在调试视图或其他适合您的地方。
Our working theory is that boto is using the wrong time zone to calculate timestamps for signing the API request, so let's enable some detailed boto3 logging that covers that area: 我们的工作原理是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)
Now try to send a message: 现在尝试发送消息:
from django.core.mail import send_mail
send_mail("Test", "testing", None, ['success@simulator.amazonses.com'])
You should see log output that looks something like this: 您应该看到如下所示的日志输出:
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'}>
The important parts here are the dates: 这里的重要部分是日期:
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', ...}>
Notice the signature calculations are all based on the UTC date (2019-03-20)—not the current local date in my Django timezone (2019-03-19). 请注意,签名计算均基于UTC日期(2019-03-20) - 而不是我的Django时区(2019-03-19)中的当前本地日期。
So it looks like boto3 does use UTC for the signature calculations, despite the Django/environment time zone. 所以看起来boto3 确实使用UTC进行签名计算,尽管有Django /环境时区。 And indeed, the send works for me without error.
事实上,发送对我没有错误。
So the question is, what's different when you see the problem? 所以问题是,当你看到问题时有什么不同?
Authorization
and X-Amz-Date
? Authorization
和X-Amz-Date
? (If you see a Date
header instead of X-Amz-Date
, that would also be interesting.) Date
标头而不是X-Amz-Date
,那也会很有趣。) Hope that helps you either get a little closer to a solution, or at least figure out what detail is essential to reproducing the problem. 希望能帮助您更接近解决方案,或者至少弄清楚哪些细节对于重现问题至关重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.