Django 发送email,ssl握手失败

Django 发送邮件,原来是可以的,后来照抄到新的环境之后报错

def send_email(request):
    send_to=['xxxx@qq.com']
    msg = EmailMultiAlternatives('主题', '测试', 'hvacreport@friendofhvac.com', send_to)
    msg.attach_alternative('测试', "text/html")
    msg.send()
    

[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1002)

百度+gpt了一下,说是新版本的python加强了SLL验证
于是改成了

from django.core.mail import EmailMultiAlternatives
import ssl
import smtplib



ctx = ssl.create_default_context()
ctx.set_ciphers('DEFAULT')

with smtplib.SMTP("mail.safemail.it", 587) as server:
    server.starttls(context=ctx)


# Create your tests here.

def send_email(request):
    send_to=['xxxx@qq.com']
    msg = EmailMultiAlternatives('主题', '测试', 'hvacreport@friendofhvac.com', send_to)
    msg.attach_alternative('测试', "text/html")
    msg.send()
    


然后变成了连接不上TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。

应该怎么弄呢?

TechWhizKid参考GPT回答:

看起来你正在尝试通过SMTP服务器发送邮件,而在迁移到新的环境后遇到了SSL握手失败的问题。当你改变了SSL的默认环境和加密套件后,你遇到了连接超时的问题。

这个问题可能有很多可能的原因,我会尝试给出一些可能帮助解决问题的建议:

  1. 检查SMTP服务器的设置和访问权限:请确保你的新环境被允许访问SMTP服务器。尤其是如果你在运行你的应用程序的机器或网络有任何防火墙设置,可能会阻止你的应用程序连接到SMTP服务器。

  2. 检查SMTP服务器的端口和SSL/TLS设置:在你的代码中,你尝试连接到SMTP服务器的端口是587,这通常是用于STARTTLS命令的端口,该命令会将现有的、未加密的SMTP连接升级为加密的连接。但是,如果你的SMTP服务器要求或期望使用SSL/TLS从一开始就加密连接,那么可能需要使用端口465,而不是端口587。

  3. 调整SSL环境的配置:你的代码已经尝试创建一个新的SSL环境,并设置其使用默认的加密套件。但是,这可能并不适合你的SMTP服务器。你可能需要找出SMTP服务器所需的具体加密套件,并将其设置在你的SSL环境中。

  4. 检查Python和Django的版本:你提到了新版本的Python增强了SSL验证,但你没有提供具体的版本号。确保你的Python和Django版本是最新的,或者至少是你的SMTP服务器所支持的版本。

给你改了一下,你看看

from django.core.mail import EmailMultiAlternatives
import ssl
import smtplib
 
 
# 创建SSL上下文
ctx = ssl.create_default_context()
ctx.set_ciphers('DEFAULT')
 
# 连接SMTP服务器
with smtplib.SMTP("mail.safemail.it", 587) as server:
    server.starttls(context=ctx)   # 启用TLS加密
 
    # 登录SMTP服务器(如果需要)
    server.login("your_username", "your_password")
 
    # 发送邮件
    send_to=['xxxx@qq.com']
    msg = EmailMultiAlternatives('主题', '测试', 'hvacreport@friendofhvac.com', send_to)
    msg.attach_alternative('测试', "text/html")
    msg.send()

更换其他SMTP服务器进行测试,例如:

with smtplib.SMTP("smtp.gmail.com", 587) as server,试了暂无报错



```bash

ctx = ssl.create_default_context()
ctx.set_ciphers('DEFAULT')
 
# # 连接SMTP服务器

def send_email():
    # with smtplib.SMTP("smtp.gmail.com", 587) as server:
    with smtplib.SMTP("mail.safemail.it", 587) as server:
        server.starttls(context=ctx)   # 启用TLS加密
    
        # 登录SMTP服务器(如果需要)
        server.login("vaillantheating@qq.com", "zomgpstvljjqcbjh")
    
        # 发送邮件
        send_to=['76032636@qq.com','1017752023@qq.com']
        msg = EmailMultiAlternatives('主题', '测试', 'vaillantheating@qq.com', send_to)
        msg.attach_alternative('测试', "text/html")
        msg.send()


send_email()

你试试直接运行呢,我运行这个,反馈是TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。

def send_email():
    with smtplib.SMTP("smtp.gmail.com", 587) as server:
    # with smtplib.SMTP("mail.safemail.it", 587) as server:
        server.starttls(context=ctx)   # 启用TLS加密
    
        # 登录SMTP服务器(如果需要)
        server.login("vaillantheating@qq.com", "zomgpstvljjqcbjh")
    
        # 发送邮件
        send_to=['76032636@qq.com','1017752023@qq.com']
        msg = EmailMultiAlternatives('主题', '测试', 'vaillantheating@qq.com', send_to)
        msg.attach_alternative('测试', "text/html")
        msg.send()


send_email()

```

然后这个,报同样的错误,你用我的代码实施试试看呢?

试一下这个方法


import imaplib
import ssl
ctx = ssl.create_default_context()
ctx.set_ciphers('DEFAULT')
imapSrc = imaplib.IMAP4_SSL('mail.safemail.it', ssl_context = ctx)

问题点: ①测试环境和正式环境存在差异,那就调一致性. ②不一定是运行环境问题,可能是正式环境无法访问SMTP服务器.
解决方法:麻烦一点的做法就是更新测试环境,修改代码,简单点就是改正式环境的.如果是问题②, 这个让运维好好确认一下,服务和端口号.

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    解决方案: 经过对参考资料的分析,我们可以得知该问题的原因可能与SSL证书有关。因此,在解决该问题前,需要确定邮件服务器是否需要SSL验证。如果需要,我们需要为Django项目配置SSL证书(证书可以自己生成,也可以购买)。

    步骤1: 确定邮件服务器是否需要SSL验证 可以通过邮件服务器提供的文档或询问邮件服务器管理员来确定。

    步骤2: 为Django项目配置SSL证书 如果需要SSL验证,可以参考参考资料中的步骤1,生成一个测试版证书。具体步骤为:

    1.下载openssl-0.9.8k_WIN32软件,并解压到本地。

    2.进入解压后的bin文件夹,双击打开openssl.exe。

    3.执行以下命令,生成server.key文件: genrsa -des3 -out server.key 2048

    4.执行以下命令,生成server.csr文件: req -new -key server.key -out server.csr -config openssl.cnf

    5.执行以下命令,生成server_no_passwd.key文件: rsa -in server.key -out server_no_passwd.key

    6.执行以下命令,生成server.crt文件: x509 -req -days 365 -in server.csr -signkey server_no_passwd.key -out server.crt

    7.将生成的server.crt和server_no_passwd.key文件复制到Django项目所在目录的同级目录下。

    步骤3: 配置Django项目发送邮件所需的参数 在Django项目的settings.py文件中,需要进行如下配置:

    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = '邮件服务器地址' EMAIL_PORT = '邮件服务器端口号' EMAIL_USE_SSL = True EMAIL_USE_TLS = False EMAIL_SSL_CERTFILE = '/path/to/cert.crt' EMAIL_SSL_KEYFILE = '/path/to/cert_no_passwd.key'

    如果需要用户名和密码进行身份验证,可以进行如下配置:

    EMAIL_HOST_USER = '用户名' EMAIL_HOST_PASSWORD = '密码'

    在上述参数配置中,需要注意的是:

    1.如果使用SSL验证,需要将EMAIL_USE_SSL设置为True,同时设置EMAIL_SSL_CERTFILE和EMAIL_SSL_KEYFILE参数为生成的证书文件的路径。

    2.EMAIL_HOST_USER和EMAIL_HOST_PASSWORD参数根据需要进行配置,如果不需要需要身份验证,则不需要配置。

    3.需要根据具体邮件服务器的设置,根据实际情况修改EMAIL_HOST和EMAIL_PORT参数。

    完成上述步骤后,可以尝试重新运行Django程序发送邮件,并检查是否出现错误。如果仍然出现问题,建议通过邮件服务器提供的文档或联系邮件服务器管理员,了解更详细的错误信息。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

报的错是超时异常,看看邮箱服务器主机地址是否正确,发送方,接收方的邮箱地址是否正确。

确保你正在使用正确的邮箱服务器和端口进行邮件发送。在你的代码中,你使用了"mail.safemail.it"和端口587。确认这些信息与你所使用的邮箱提供商的设置相匹配。

确认你的网络连接是否正常,尝试使用其他网络连接进行测试。

检查邮件服务器的设置是否正确,包括端口号、用户名、密码等。

确认邮件服务器是否支持 SSL/TLS 加密,如果不支持,可以尝试使用普通的 SMTP 连接。

尝试调整连接的超时时间,有些邮件服务器可能需要更长时间才能建立连接。

如果以上方法都没有解决问题,可以尝试使用其他的邮件发送库,比如 yagmail 或者 mailer 等。

在你的python程序文件开头加上以下两行代码,可以解决你的这个sslv3 alert handshake failure的报错问题:

import requests.packages.urllib3.util.ssl_
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL'

检查一下服务器是否支持加密,另外可以安装回原来的python版本,看看能正常发送不