我有一个使用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 dev环境中使用主机名字符串工作正常。
下面是一个代码摘录:
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
个字符
如果我将下面这行添加到我的设置中(经过数小时的搜索后从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模块,但是我不知道我需要做些什么来克服这一点。如果有人能给我指出正确的方向,我会非常感激。
1条答案
按热度按时间3phpmpom1#
经过多次尝试和错误,我将EMAIL_HOST设置更改为:
字符串
现在,证书域与连接域匹配,而之前它是一个不匹配的IP地址。
这是一个有点不满意,但它可能会帮助其他人。
顺便说一句,从我的Linux服务器连接时的长时间延迟似乎也消失了。也许在其中一个软件包的后期版本中有什么东西被修复了。