如何在Python请求中禁用安全证书检查


230

我在用

import requests
requests.post(url='https://foo.com', data={'bar':'baz'})

但我收到了request.exceptions.SSLError。该网站的证书已过期,但是我没有发送敏感数据,因此对我来说无关紧要。我可以想象有一个像'verifiy = False'这样的参数可以使用,但是我似乎找不到。

Answers:


411

文档中

requests如果设置verify为False,也可以忽略验证SSL证书 。

>>> requests.get('https://kennethreitz.com', verify=False)
<Response [200]>

如果您使用的是第三方模块,并且想禁用检查功能,则可以使用上下文管理器来修补requests和更改它,从而使它verify=False成为默认设置并禁止显示警告。

import warnings
import contextlib

import requests
from urllib3.exceptions import InsecureRequestWarning


old_merge_environment_settings = requests.Session.merge_environment_settings

@contextlib.contextmanager
def no_ssl_verification():
    opened_adapters = set()

    def merge_environment_settings(self, url, proxies, stream, verify, cert):
        # Verification happens only once per connection so we need to close
        # all the opened adapters once we're done. Otherwise, the effects of
        # verify=False persist beyond the end of this context manager.
        opened_adapters.add(self.get_adapter(url))

        settings = old_merge_environment_settings(self, url, proxies, stream, verify, cert)
        settings['verify'] = False

        return settings

    requests.Session.merge_environment_settings = merge_environment_settings

    try:
        with warnings.catch_warnings():
            warnings.simplefilter('ignore', InsecureRequestWarning)
            yield
    finally:
        requests.Session.merge_environment_settings = old_merge_environment_settings

        for adapter in opened_adapters:
            try:
                adapter.close()
            except:
                pass

使用方法如下:

with no_ssl_verification():
    requests.get('https://wrong.host.badssl.com/')
    print('It works')

    requests.get('https://wrong.host.badssl.com/', verify=True)
    print('Even if you try to force it to')

requests.get('https://wrong.host.badssl.com/', verify=False)
print('It resets back')

session = requests.Session()
session.verify = True

with no_ssl_verification():
    session.get('https://wrong.host.badssl.com/', verify=True)
    print('Works even here')

try:
    requests.get('https://wrong.host.badssl.com/')
except requests.exceptions.SSLError:
    print('It breaks')

try:
    session.get('https://wrong.host.badssl.com/')
except requests.exceptions.SSLError:
    print('It breaks here again')

请注意,一旦您离开上下文管理器,此代码将关闭处理已打补丁请求的所有打开的适配器。这是因为请求维护每个会话的连接池,并且证书验证每个连接仅进行一次,因此将发生以下意外情况:

>>> import requests
>>> session = requests.Session()
>>> session.get('https://wrong.host.badssl.com/', verify=False)
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:857: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
<Response [200]>
>>> session.get('https://wrong.host.badssl.com/', verify=True)
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:857: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
<Response [200]>

6
谢谢,如果您在自己的代码中只有很少的请求调用,则可以使用此方法,但是想像一下,我想在使用请求的第三个部分库中禁用它,...将无法像这样修复第三方库。
索林2013年

7
@sorin:只是猴子补丁requestsverify默认设置为False
Blender

2
如何抑制仍然打印的令人讨厌的大警告消息?
迈克尔

27
@Michael回答我自己的问题:requests.packages.urllib3.disable_warnings()
Michael

8
@迈克尔:或避免隐藏所有的警告:from urllib3.exceptions import InsecureRequestWarning然后requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
塞巴斯蒂安Deprez

96

使用requests.packages.urllib3.disable_warnings()verify=Falseon requests方法。

import requests
from urllib3.exceptions import InsecureRequestWarning

# Suppress only the single warning from urllib3 needed.
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

# Set `verify=False` on `requests.post`.
requests.post(url='https://example.com', data={'bar':'baz'}, verify=False)

11
当您想要摆脱“正在发出未验证的HTTPS请求”之类的警告时,您的答案很有用。但是verify=False无论如何必须出席。Tnx。
卢法

17
并避免隐藏所有的警告:from urllib3.exceptions import InsecureRequestWarning然后requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
塞巴斯蒂安Deprez

对于无法禁用警告的用户,可以尝试requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)。之所以有效,urllib3.exceptions.InsecureRequestWarning是因为它确保正确使用requests
AnnieFromTaiwan

32

要添加到Blender的答案中,您可以使用禁用所有请求的SSLSession.verify = False

import requests

session = requests.Session()
session.verify = False
session.post(url='https://foo.com', data={'bar':'baz'})

请注意urllib3,(请求使用),强烈建议您不要发送未经验证的HTTPS请求,并会引发InsecureRequestWarning


11

也可以从环境变量中完成:

export CURL_CA_BUNDLE=""

1
这给了我:“OSERROR:找不到合适的TLS CA证书捆绑的,无效的路径:‘’我使用的要求2.22.0。
哈伊姆

export REQUESTS_CA_BUNDLE='your-ca.pem'

1
如果您需要使用无法编辑的库,这似乎是最好的答案
user989762

基于CURL_CA_BUNDLEos.environ['REQUESTS_CA_BUNDLE'] = 'FiddlerRootCertificate_Base64_Encoded_X.509.cer.pem' # your-ca.pem当使用google-cloud-bigquery 1.24.0BigQuery Client Lib for Python
samm

8

如果您想使用verify = False选项发送准确的发布请求,最快的方法是使用以下代码:

import requests

requests.api.request('post', url, data={'bar':'baz'}, json=None, verify=False)

当您禁用verify = False时,强盗不会高兴。请参阅:docs.openstack.org/bandit/latest/plugins/...
kRazzy [R

嗨,我有一个请求,通过禁用设置选项中的“ SSL证书验证”,可以使我在邮递员中回复请求。但是,如果我获得了邮递员提供的python请求代码,则将收到“ SSL例程”,“ tls_process_server_certificate”,“证书验证失败”错误,并且添加“ verify = False”在这种情况下无济于事。有什么解决方案可以在python请求脚本中获得Postman的响应?
Taha Hamedani
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.