来自 EC2 的 Django send_mail() 通过 Gmail 提供 SMTPAuthenticationError - 但在 localhost 中工作正常

Posted

技术标签:

【中文标题】来自 EC2 的 Django send_mail() 通过 Gmail 提供 SMTPAuthenticationError - 但在 localhost 中工作正常【英文标题】:Django send_mail() from EC2 via Gmail gives SMTPAuthenticationError - but works fine in localhost 【发布时间】:2016-06-10 02:36:25 【问题描述】:

Django 项目settings.py 包括以下内容:

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.gmail.com"
EMAIL_HOST_USER = "you.cant.see.me@gmail.com"
EMAIL_HOST_PASSWORD = "thug_life"
EMAIL_PORT = 587
EMAIL_USE_TLS = True

我的应用程序的views.py 包含以下内容

def send_classic_email(request):
    from django.core.mail import send_mail
    send_mail(
        subject = "Tale of two cities",
        from_email = "Charles Dickens <you.cant.see.me@gmail.com>",
        recipient_list = ["someone@example.com"],
        message = "There were 2 cities",
        html_message = "<p>There were 2 cities</p>",
        fail_silently = False,
    )
    print "Absolutely Perfectly Done"

从本地主机尝试。得到SMTPAuthenticationError作为回报:

SMTPAuthenticationError at /send_classic_email/
(534, '1.3.95 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=fsadjSADJH\n1.3.95 
fjkshFHAKSHkdfshkfkhj-sfjdhFsadASDA_\n1.3.95 
dasdASDADas-aDas-hfhjsadASDSAhjjhd\n1.3.95 
ADSaSADkja_adhjkADKjhads-ASADS_SDAKjadAKJhsADS-k\n1.3.95 
sadhkjADSAKJSDJAlkjdaA> Please log in via your web browser and\n1.3.95 
then try again.\n1.3.95  
Learn more at\n1.3.95  
https://support.google.com/mail/answer/78754 dkahASDASlkjdas.25 - gsmtp')

然后访问https://www.google.com/settings/security/lesssecureapps并启用less secure app设置。

之后,从 localhost 再次尝试。明白了:

完美无缺

在 AWS EC2 上部署了这段代码。从 EC2 尝试过。再次得到相同的SMTPAuthenticationError

SMTPAuthenticationError at /send_classic_email/
(534, '1.3.95 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=fsadjSADJH\n1.3.95 
fjkshFHAKSHkdfshkfkhj-sfjdhFsadASDA_\n1.3.95 
dasdASDADas-aDas-hfhjsadASDSAhjjhd\n1.3.95 
ADSaSADkja_adhjkADKjhads-ASADS_SDAKjadAKJhsADS-k\n1.3.95 
sadhkjADSAKJSDJAlkjdaA> Please log in via your web browser and\n1.3.95 
then try again.\n1.3.95  
Learn more at\n1.3.95  
https://support.google.com/mail/answer/78754 dkahASDASlkjdas.25 - gsmtp')

前往 EC2 安全组:

所有来源SMTP 端口 的入站规则已启用。 所有端口通过所有协议所有目的地所有流量的出站规则已启用。

仍然得到相同的SMTPAuthenticationError

为什么它在 localhost 而不是 EC2 实例上运行良好?

Ubuntu 14.04.3 LTSPython 2.7.6 上运行Django 1.8.0

【问题讨论】:

您可能需要解锁验证码才能让 Django 为您发送:accounts.google.com/displayunlockcaptcha 好的...我会尝试...但是它如何解释从我的本地主机工作正常并从 EC2 工作? @jape... 它确实有效。请用这个写一个正确的 *** 答案,以便我可以接受。但是,我仍然不明白为什么它在 localhost 而不是从 EC2 工作正常,直到我转到您共享的链接 【参考方案1】:

您可能需要解锁 Captcha 才能让 Django 为您发送:accounts.google.com/displayunlockcaptcha

验证码是您需要在表单中输入才能进入下一页的小字符。这是大多数公司所依赖的安全预防措施。

您能够在本地主机上逃脱它的原因是因为您本质上是控制验证码的公司。您是在告诉您的服务器,“无论如何都发送;它是安全的。”但是,在这种情况下,Google 控制着验证码。由于您使用的是亚马逊,因此阻止电子邮件是谷歌保护其服务器并确保亚马逊不是垃圾邮件的一种方式。点击该链接,即表示您告诉 Google 允许通过您的电子邮件进行所有传出连接。

这有意义吗?

【讨论】:

这个解决方案确实有效。但是,谷歌如何评估来自 localhost 的请求是由我发出的,而来自 EC2 的请求不是由我发出的?我不明白。 @syedrakib 验证码用于检测新设备是否正在尝试访问您的帐户。我假设您之前(本地主机)已经从您的计算机访问了您的电子邮件。 Google 为您的机器开了绿灯。这可能是亚马逊第一次访问它。你需要告诉谷歌允许亚马逊进入。 @syedrakib 我很高兴!祝你好运:) 谢谢.. 这对我有帮助。 @jape【参考方案2】:

我感觉亚马逊不允许这样做。他们真的不希望您从他们的服务器发送邮件,所以他们阻止了它。基本上,这是为了避免垃圾邮件发送者,他们过去常常通过虚拟卡车从 EC2 发送电子邮件。我建议您使用类似 mailgun(或 SES,如果您真的喜欢 AWS,但我可能不会)来处理发送电子邮件。有一个很好的django email backend for mailgun,所以你根本不需要改变你的代码。

【讨论】:

你是认真的吗? AWS 会阻止我尝试通过 django 发送电子邮件,但在使用 mailgun 时不会阻止我? 是的,因为 mailgun 使用 REST API 而不是 SMTP。 如果您使用非默认端口,您似乎也可以使用 SMTP。

以上是关于来自 EC2 的 Django send_mail() 通过 Gmail 提供 SMTPAuthenticationError - 但在 localhost 中工作正常的主要内容,如果未能解决你的问题,请参考以下文章

Django,send_mail,没有足够的值来解包

如何在 Django 中测试 send_mail?

Django中的Send_mail,在shell中工作,在本地工作,不在视图中

Django 收到错误:send_mail() 在发送邮件时收到了意外的关键字参数“fail_silently”

Django 发送 Gmail using.core.mail import send_mail: ConnectionRefusedError: No connection could be mad

python测试开发django-28.发送邮件