Flask-Mail 未使用 Gmail 和应用密码进行身份验证

Posted

技术标签:

【中文标题】Flask-Mail 未使用 Gmail 和应用密码进行身份验证【英文标题】:Flask-Mail not Authenticating with Gmail and App password 【发布时间】:2019-01-21 07:09:00 【问题描述】:

因此,当我尝试使用我构建的烧瓶应用程序发送电子邮件时,我收到了 SMTPSenderRefused 错误。让我开始购买,说这以前有效,但现在已经停止了。我很茫然,我花了很多时间在网上测试、调整和阅读,但没有什么能给我答案。

我不断收到以下错误。

[2019-01-21 03:07:51,954] ERROR in app: Exception on /register/ [POST]
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "MyFlaskApp.py", line 131, in register
    mail.send(msg)
  File "/usr/local/lib/python2.7/site-packages/flask_mail.py", line 492, in send
    message.send(connection)
  File "/usr/local/lib/python2.7/site-packages/flask_mail.py", line 427, in send
    connection.send(self)
  File "/usr/local/lib/python2.7/site-packages/flask_mail.py", line 192, in send
    message.rcpt_options)
  File "/usr/lib64/python2.7/smtplib.py", line 737, in sendmail
    raise SMTPSenderRefused(code, resp, from_addr)
SMTPSenderRefused: (530, '5.5.1 Authentication Required. Learn more at\n5.5.1  https://support.google.com/mail/?p=WantAuthError u186sm20332024pfu.51 - gsmtp', u'myemail@gmail.com')
IP.XX.XXX.XXX - - [21/Jan/2019 03:07:51] "POST /register/ HTTP/1.1" 500 -

我的 gmail 帐户配置了两步验证,然后是此 Flask 应用程序使用的应用程序密码。我已经尝试了所有组合,但仍然无法正常工作。这是我正在使用的代码。

app = Flask(__name__, static_url_path='/static')
app.config.update(
  DEBUG = False,
  MAIL_SERVER = 'smtp.gmail.com',
  MAIL_PORT = 465,
  MAIL_USE_SSL = True,
  MAIL_USERNAME = 'myemail@gmail.com',
  MAIL_DEFAULT_SENDER = 'myemail@gmail.com',
  MAIL_PASSWORD = 'GmailApplicationPassword',
  )
mail = Mail(app)

实际发送消息的行(在 POST 内):

    msg = Message("Welcome",
      sender = 'myemail@gmail.com',
      recipients = [request.form["email"]])
    msg.body = "Welcome! \n\n Congratulations on your successful registration. \n\n Cheers!"
    mail.send(msg)

一些可能有用的附加信息。当我在本地运行我的应用程序时,这个确切的代码曾经可以工作。然后我将我的代码部署到我的 AWS EC2 实例并让它在那里运行。在我执行以下操作之前,它一直在工作。

我将一个弹性 IP 地址与该站点相关联,然后将我的 DNS 指向该 IPv4。我还添加了 AWS 公共证书。

谁能帮我理解为什么我无法发送电子邮件。我已经尝试了所有可以在网上找到的解决方案。

其他细节:

$ pip freeze
Flask-Mail==0.9.1

提前致谢,如果需要更多说明,我将帮助提供任何答案,所以请询问。

【问题讨论】:

如果它不是清除的。 两步验证已启用,并且该应用具有特定的应用密码。此功能意味着“允许不太安全的应用访问”选项不可用。 我也坚持了好几个小时。你找到解决办法了吗? @alpaca 我无法让 gmail 接受来自 AWS 的传入连接。我尝试了一切,但它不起作用(我什至尝试手动连接命令行)。最终,我设置了 AWS 简单电子邮件服务。我使用Flask-MailAWS SES 建立连接,然后与AWS SES 建立与gMail 的连接。我还必须请求提高 SES 费率,因为您只能在免费套餐内使用测试电子邮件,而且我需要能够在我的生产环境中发送外部电子邮件。问题是 Gmail 不会验证或允许 AWS IP 连接和发送电子邮件。 也遇到此错误,适用于我的私人@gmail 帐户,但不适用于我的公司电子邮件。有没有人碰巧找到解决方案? 【参考方案1】:

这是我发现效果最好的解决方案。 (我并不是说这是最好的方法,但它确实有效)它涉及到使用我强烈推荐使用的几个不同的关键概念。它涉及秘密的使用,您可以关注此guide here 以获取更多信息(因为它不是这个问题的核心,我只会在此处留下一个链接)。它还需要使用Boto3 才能读取变量。 AWS 文档在这里会很有帮助,所以我不再包括它。

我的方法是设置 AWS 简单电子邮件服务 (SES)。这使得使用 Flask-Mail 的应用程序访问 AWS SES 以发送电子邮件,然后与 gmail 对话以实际发送电子邮件。这里的一些重要注意事项是 SES 并非在每个区域,但目前(2019 年 6 月)不需要将您的 EC2 实例托管在您使用 SES 的同一区域中。此外,如果您希望能够向外部地址发送电子邮件,则必须确保您的电子邮件收件箱已按照 AWS 使用条款进行配置且不违反 AWS 使用条款。最后,如果您使用免费套餐,则必须提交支持票以提高费率,并且还允许您向外部发送电子邮件。现在这是我使用的代码:

app = Flask(__name__, static_url_path='/static')
app.config.update(
  DEBUG = False,
  MAIL_SERVER = params.getParameter("SES_SERVER"),
  MAIL_PORT = 587,
  MAIL_USE_TLS = True,
  MAIL_USERNAME = params.getParameter("SES_USERNAME"),
  MAIL_PASSWORD = params.getParameter("SES_PASSWORD"),
  )
mail = Mail(app)

发送代码保持不变。 我确实需要为Boto3 添加一个导入,并创建了一个名为params.py 的新文件,并且我在其中构建了我的getParameter 方法来访问变量。如果您愿意,您可以对上面的值进行硬编码,但我不建议这样做,特别是如果您将代码存储在云存储库中。

我不能 100% 确定,但我怀疑 gmail 禁止 AWS 访问其服务器的 IP 地址或域,因此您无法发送电子邮件。这是我的怀疑,但我找不到证明它的方法。

【讨论】:

【参考方案2】:

对于已激活两步验证的 gmail 帐户,禁用安全性较低的应用。在这种情况下访问应用程序密码需要生成。

这是用烧瓶应用编写的应用配置代码。

`app = Flask(__name__)
 app.config.update(
   MAIL_SERVER = "smtp.gmail.com",
   MAIL_PORT="465",
   MAIL_USE_SSL=True,
   MAIL_USERNAME=params['gmail-user'],
   MAIL_PASSWORD=params['gmail-pass']  
   )
 mail=Mail(app)`

创建“config.json”来定义参数,将在上面使用。对于用户名和密码,请检查“gmail-user”和“gmail-pass”

"params":
       "local_server":"True",
        "local_uri":"mysql+pymysql://root:@localhost/jbh_datasc_blog",
        "prod_uri": "mysql+pymysql://root:@localhost/jbh_datasc_blog",
        "fb_url":"https://facebook.com/<give the name of extension>",
        "tw_url":"https://twitter.com/<give the name of extension>",
        "gh_url":"https://github.com/<give the name of extension>",
        "blog_head":"Data Science Digital",
        "sub_head":"Innovating Future",
        "gmail-user":"xxxxxxxx@gmail.com",
        "gmail-pass":"xxxxxxxxxxxxxxxx"    
    

    转到您的 gmail 帐户并在搜索栏中输入应用密码。 它会询问你访问的应用程序和计算机的名称,提供它。 Google 会生成一个 16 位的密码。 使用此密码填写“gmail-pass” 保存并执行代码。

【讨论】:

嘿,我已经这样做了,但它仍然无法正常工作。我在 Ubuntu/nginx 服务器上运行 Flask 应用程序。秘密保存在 /etc/appname/appname.json 我需要做些什么来用新密码重新加载应用程序吗?

以上是关于Flask-Mail 未使用 Gmail 和应用密码进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

配置 Flask-Mail 以使用 GMail

配置 Flask-Mail 以使用 GMail

使用flask-mail通过gmail发送电子邮件

使用flask-mail发送电子邮件时出现的问题

Flask 学习-61.Flask-Mail 发送邮件

Flask-mail 批量发送 HTML 电子邮件,在 html 中使用波斯语字体