use*_*601 13 python ssl oauth certificate ssl-certificate
每当尝试在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'])
Run Code Online (Sandbox Code Playgroud)
以及Python解释器中的这些错误:
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
Run Code Online (Sandbox Code Playgroud)
现在,就这样知道,我有我的cacerts.txt与httplib2在适当的地方附带,它被发现,但我仍然有这个问题.任何帮助表示赞赏,谢谢!
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())
Run Code Online (Sandbox Code Playgroud)
如示例所示,在最近的软件版本上,默认CA列表可能已足够.
小智 7
首先,跑pip install certifi.然后在发出任何请求之前设置客户端的ca_certs属性:
client = oauth.Client(consumer)
client.ca_certs = certifi.where()
Run Code Online (Sandbox Code Playgroud)
这是受到jterrace建议使用的启发 httplib2.Http.add_certificate