Python - SSL Issue with Oauth2

前端 未结 6 1007
醉话见心
醉话见心 2020-12-14 03:41

I seem to be having an issue with SSL whenever trying to use oAuth2 in Python. I\'ve spent most of the afternoon attempting to debug it but can\'t seem to figure it out.

相关标签:
6条回答
  • 2020-12-14 04:09

    I was having the same error on my system (OSX Yosemite) which had an old version of Python 2.7 installed (2.7.1).

    I upgraded Python to 2.7.10 which solved the problem.

    https://www.python.org/downloads/release/python-2710/

    The clue was in the following warning message which I saw while I was experimenting with different solutions:

    "InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning"

    0 讨论(0)
  • 2020-12-14 04:09

    One more way to update your cacerts.txt file is to keep httplib2 up to date. They occasionally update this file, so if you run into this problem, check if you're not using the latest version of the library and update it.

    0 讨论(0)
  • 2020-12-14 04:20

    cacerts.txt contains too few CAs. If you replace it with cacert.pem then there is no ssl error. Here's a test script:

    #!/usr/bin/env python3
    import http.client
    import ssl
    
    ####context = ssl.create_default_context(cafile='cacerts.txt') # ssl.SSLError
    ####context = ssl.create_default_context(cafile='cacert.pem')  # works   
    context = ssl.create_default_context()  # works as is on the recent versions
    #NOTE: ssl.CERT_REQUIRED is set for the default Purpose.SERVER_AUTH
    
    h = http.client.HTTPSConnection('api.instagram.com', 443, context=context)
    h.request('POST', '/oauth/access_token')
    resp = h.getresponse()
    print(resp.status, resp.reason) # produce expected 400 http error
    print(resp.headers)
    print(resp.read())
    

    As the example demonstrates, the default CA list might be enough on the recent software versions.

    0 讨论(0)
  • 2020-12-14 04:22

    The default cacerts.txt that comes with httplib2 contains these certificates:

    • Verisign/RSA Secure Server CA
    • Thawte Personal Basic CA
    • Thawte Personal Premium CA
    • Thawte Personal Freemail CA
    • Thawte Server CA
    • Thawte Premium Server CA
    • Equifax Secure CA
    • Verisign Class 1 Public Primary Certification Authority
    • Verisign Class 2 Public Primary Certification Authority
    • Verisign Class 3 Public Primary Certification Authority
    • Verisign Class 1 Public Primary Certification Authority - G2
    • Verisign Class 2 Public Primary Certification Authority - G2
    • Verisign Class 3 Public Primary Certification Authority - G2
    • Verisign Class 4 Public Primary Certification Authority - G2
    • Verisign Class 1 Public Primary Certification Authority - G3
    • Verisign Class 2 Public Primary Certification Authority - G3
    • Verisign Class 3 Public Primary Certification Authority - G3
    • Verisign Class 4 Public Primary Certification Authority - G3
    • Equifax Secure Global eBusiness CA
    • Equifax Secure eBusiness CA 1
    • Equifax Secure eBusiness CA 2
    • Thawte Time Stamping CA
    • thawte Primary Root CA
    • VeriSign Class 3 Public Primary Certification Authority - G5
    • Entrust.net Secure Server Certification Authority
    • Go Daddy Certification Authority Root Certificate Bundle

    The instagram HTTPS certificate is signed by:

    • GeoTrust Global CA

    You will need to add the certificate to your cacerts.txt

    0 讨论(0)
  • 2020-12-14 04:27

    First, run pip install certifi. Then set the client's ca_certs property, before making any requests:

    client = oauth.Client(consumer)
    client.ca_certs = certifi.where()
    

    This was inspired by jterrace's suggestion to use httplib2.Http.add_certificate

    0 讨论(0)
  • 2020-12-14 04:30

    I was running into the same issue with Flask-Social's OAuth call to Facebook. The easiest solution is to install httplib2.ca_certs_locator plug-in.

    In httplib2.init.py, there is a check built-in for loading certificates from another source instead of the cacerts.txt file provided with the library:

    try:
        # Users can optionally provide a module that tells us where the CA_CERTS
        # are located.
        import ca_certs_locater
        CA_CERTS = ca_certs_locater.get()
    except ImportError:
        # Default CA certificates file bundled with httplib2.
        CA_CERTS = os.path.join(
            os.path.dirname(os.path.abspath(__file__ )), "cacerts.txt")
    

    Installing this plug-in fixed the problem for me with no code-changes/hack-a-rounds.

    0 讨论(0)
提交回复
热议问题