logging.handlers.SMTPHandler引发smtplib.SMTPAuthenticationError

时间:2015-06-11 03:21:09

标签: python logging smtp

我尝试使用Verizon和Gmail。两台服务器都拒绝认证Gmail通过电子邮件通知我,它拒绝了登录尝试,因为该连接未使用"现代安全" 我想知道如何使用这个日志处理程序来使用现代安全性。

logging.handlers.SMTPHandler(mailhost=('', 25),
                             fromaddr='',
                             toaddrs='',
                             subject='',
                             credentials=('username','password'),
                             secure=())

2 个答案:

答案 0 :(得分:6)

对于任何回到此处的人,以下是我使用Gmail处理SMTPHandler的方法:

eh = SMTPHandler(mailhost=('smtp.gmail.com', 587),
                fromaddr=from_addr,
                toaddrs=to_addrs,
                subject=subject,
                credentials=(username, password),
                secure=())

我的示例中的to_addrs变量是一个字符串。我不确定它是否可以是数组或者应该是空格或逗号分隔的字符串。 username变量包含域名,如下所示:foo@gmail.com

大多数导游说使用端口465,如果你好奇,这里是difference。但是,当我尝试使用端口465时,我收到了SMTP超时错误:

Traceback (most recent call last):
File "/usr/local/lib/python3.5/smtplib.py", line 386, in getreply
  line = self.file.readline(_MAXLINE + 1)
File "/usr/local/lib/python3.5/socket.py", line 571, in readinto
  return self._sock.recv_into(b)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.5/logging/handlers.py", line 972, in emit
  smtp = smtplib.SMTP(self.mailhost, port, timeout=self.timeout)
File "/usr/local/lib/python3.5/smtplib.py", line 251, in __init__
  (code, msg) = self.connect(host, port)
File "/usr/local/lib/python3.5/smtplib.py", line 337, in connect
  (code, msg) = self.getreply()
File "/usr/local/lib/python3.5/smtplib.py", line 390, in getreply
  + str(e))
smtplib.SMTPServerDisconnected: Connection unexpectedly closed: timed out

我切换到端口587并且Google成功通过身份验证。消息已发送。

答案 1 :(得分:5)

Gmail问题:

  • 这里没有提到。请参阅有关Gmail应用验证的其他答案。

Verizon问题:

  • 某些邮件提交服务器可能只接受端口465上的SMTPS。请参阅What is the difference between ports 465 and 587?进行详细说明。 Verizon邮件提交服务器smtp.verizon.net就是一个这样的例子。
  • SMTPHandler默认情况下不支持SMTPS。您可以对功能进行monkeypatch。

解决方案:

  • 这会强制任何服务器使用SMTPS。
  • 更全面的解决方法是使用标志编辑类以启用SMTPS。

  1. 将编辑后的发射功能从下方粘贴到相关文件中。
  2. 然后设置

    logging.handlers.SMTPHandler.emit = emit
    
  3. 默认的/logging/handlers.py logging.handlers.SMTPHandler.emit功能

    # Class SMTPHandler...
    def emit(self, record):
        """
        Emit a record.
    
        Format the record and send it to the specified addressees.
        """
        try:
            import smtplib
            from email.utils import formatdate
            port = self.mailport
            if not port:
                port = smtplib.SMTP_PORT
            smtp = smtplib.SMTP(self.mailhost, port, timeout=self._timeout)
            msg = self.format(record)
            msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
                            self.fromaddr,
                            ",".join(self.toaddrs),
                            self.getSubject(record),
                            formatdate(), msg)
            if self.username:
                if self.secure is not None:
                    smtp.ehlo()
                    smtp.starttls(*self.secure)
                    smtp.ehlo()
                smtp.login(self.username, self.password)
            smtp.sendmail(self.fromaddr, self.toaddrs, msg)
            smtp.quit()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)
    

    已编辑的发射功能

    def emit(self, record):
        """
        Overwrite the logging.handlers.SMTPHandler.emit function with SMTP_SSL.
        Emit a record.
        Format the record and send it to the specified addressees.
        """
        try:
            import smtplib
            from email.utils import formatdate
            port = self.mailport
            if not port:
                port = smtplib.SMTP_PORT
            smtp = smtplib.SMTP_SSL(self.mailhost, port, timeout=self._timeout)
            msg = self.format(record)
            msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (self.fromaddr, ", ".join(self.toaddrs), self.getSubject(record), formatdate(), msg)
            if self.username:
                smtp.ehlo()
                smtp.login(self.username, self.password)
            smtp.sendmail(self.fromaddr, self.toaddrs, msg)
            smtp.quit()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)