Django 5 和 Python 3.12.1 send_mail 因 SSL 错误而失败

问题描述 投票:0回答:1

我有一个使用 Django 3.2.6 和 Python 3.9.6 的工作应用程序。我正在尝试升级到 Django 5 和 Python 3.12.1。到目前为止,我已经成功地找到并解决了由各种更改和弃用引起的许多问题,但这一个问题让我困惑了好几天。

在新环境中使用 Django

send_mail()
失败,并显示
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '40.99.213.34'. (_ssl.c:1000)

注意:我需要使用 IPV4 地址进行连接,因为在 Linux 服务器上使用实际主机名会导致大约 2 分钟的延迟,而默认 IPV6 地址会超时并回退到 IPV4。在我的 Win10 开发环境中使用主机名字符串效果很好。

这是代码摘录:

settings.py

EMAIL_HOST = socket.gethostbyname('smtp.office365.com')  # resolves IPV4 address
EMAIL_PORT = 587
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'password'
EMAIL_USE_TLS = True
views.py

send_mail('Subject','Message Body','[email protected]',['[email protected]'])

如果我将以下行添加到我的设置中(经过数小时的搜索后从 SO 收集),错误将更改为更无帮助的内容:

[SSL] PEM Lib (_ssl.c:3917)

import certifi
EMAIL_SSL_CERTFILE = certifi.where()

很明显,ssl 连接方式发生了一些变化,也许它坚持以与 Python 3.9.6 中不同的方式验证证书。我花了很多时间寻找解决方案,但毫无结果。我查看了 django smtp 模块和 python ssl 模块的源代码,甚至在绝望中查看了 cpython _ssl 模块,但我不知道需要做什么来克服这个问题。如果有人能指出我正确的方向,我将非常感激。

python django ssl upgrade
1个回答
0
投票

经过更多尝试和错误,我将 EMAIL_HOST 设置更改为:

EMAIL_HOST = 'smtp.office365.com'

现在证书域与连接域匹配,而之前是一个IP地址,不匹配。

这有点令人不满意,但可能对其他人有帮助。

顺便说一句,从我的 Linux 服务器连接的长时间延迟似乎也消失了。也许所涉及的软件包之一的后续版本中修复了某些问题。

© www.soinside.com 2019 - 2024. All rights reserved.