每当尝试在Python中使用oAuth2时,我似乎都遇到了SSL问题。我花了大部分时间试图调试它,但似乎无法弄明白。
这是我的Python脚本(很简单):
import oauth2.oauth2 as oauth
import urlparse
import time
## If you're actually processing requests, you'll want this
# import simplejson
### GET A REQUEST TOKEN ###
consumer = oauth.Consumer(key="***KEYHERE***", secret="***KEYSECRETHERE***")
request_token_url = 'https://api.instagram.com/oauth/access_token'
client = oauth.Client(consumer)
resp, content = client.request(request_token_url, "GET")
request_token = dict(urlparse.parse_qsl(content))
token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret'])
来自Python Interpreter的这些错误:
Traceback (most recent call last):
File "E:\Projects\oAuth2Test\test.py", line 16, in <module>
resp, content = client.request(request_token_url, "GET")
File "E:\Projects\oAuth2Test\oauth2\oauth2.py", line 682, in request
connection_type=connection_type)
File "E:\Projects\oAuth2Test\httplib2\httplib2.py", line 1445, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "E:\Projects\oAuth2Test\httplib2\httplib2.py", line 1197, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File "E:\Projects\oAuth2Test\httplib2\httplib2.py", line 1133, in _conn_request
conn.connect()
File "E:\Projects\oAuth2Test\httplib2\httplib2.py", line 914, in connect
raise SSLHandshakeError(e)
SSLHandshakeError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
现在,就这样知道,我有我的cacerts.txt与httplib2一起在适当的地方找到它,但我仍然有这个问题。感谢任何帮助,谢谢!
答案 0 :(得分:8)
cacerts.txt
包含的CA太少。如果用cacert.pem替换它,那么就没有ssl错误。这是一个测试脚本:
#!/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())
如示例所示,在最近的软件版本上,默认CA列表可能已足够。
答案 1 :(得分:7)
首先,运行pip install certifi
。然后在发出任何请求之前设置客户端的ca_certs属性:
client = oauth.Client(consumer)
client.ca_certs = certifi.where()
这是受到jterrace建议使用httplib2.Http.add_certificate
答案 2 :(得分:2)
httplib2附带的默认cacerts.txt包含以下证书:
Instagram HTTPS证书由以下人员签署:
您需要将证书添加到cacerts.txt
答案 3 :(得分:2)
我遇到了与Flask-Social的OAuth调用Facebook相同的问题。最简单的解决方案是安装httplib2.ca_certs_locator插件。
在httplib2。 init .py中,内置了一个用于从其他来源加载证书的检查,而不是随库提供的cacerts.txt文件:
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")
安装此插件解决了我的问题,没有代码更改/黑客攻击。
答案 4 :(得分:0)
我的系统(OSX Yosemite)上安装了旧版本的Python 2.7(2.7.1)时遇到了同样的错误。
我将Python升级到2.7.10,解决了这个问题。
https://www.python.org/downloads/release/python-2710/
我在尝试不同的解决方案时看到了以下警告信息:
“InsecurePlatformWarning:真正的SSLContext对象不可用。这可以防止urllib3正确配置SSL,并可能导致某些SSL连接失败。有关详细信息,请参阅https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning”
答案 5 :(得分:0)
更新cacerts.txt
文件的另一种方法是让httplib2
保持最新状态。他们偶尔会更新此文件,因此如果您遇到此问题,请检查您是否使用了最新版本的库并进行更新。