Django中的urllib2/pycurl:获取XML,检查HTTP状态,验证HTTPS连接
我需要在Django中进行一次类似API调用的操作,这是我们自定义认证系统的一部分。用户的用户名和密码会通过SSL发送到一个特定的URL(用GET方法传递这些参数),然后服务器会返回一个HTTP 200 "OK"的响应,响应内容是包含用户信息的XML格式。
如果认证失败,服务器会返回一个HTTP 401 "Unauthorized"的响应。
出于安全考虑,我需要检查以下几点:
- 请求是通过HTTPS连接发送的
- 服务器证书的公钥与预期的值匹配(我使用“证书钉扎”来防止不可靠的证书颁发机构)
请问在Python/Django中,使用pycurl/urllib2或其他方法可以做到这一点吗?
2 个回答
0
httplib2 可以用来发送 https 请求,并且能够验证证书:
import httplib2
http = httplib2.Http(ca_certs='/path/to/cert.pem')
try:
http.request('https://...')
except httplib2.SSLHandshakeError, e:
# do something
只要确保你的 httplib2 是最新版本。我的系统(ubuntu 10.04)自带的版本没有 ca_certs
这个参数。
另外,关于你提到的类似问题,这里有一个使用 pycurl 进行证书验证的例子。
3
使用 M2Crypto:
from M2Crypto import SSL
ctx = SSL.Context('sslv3')
ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9)
if ctx.load_verify_locations('ca.pem') != 1:
raise Exception('No CA certs')
c = SSL.Connection(ctx)
c.connect(('www.google.com', 443)) # automatically checks cert matches host
c.send('GET / \n')
c.close()
使用 urllib2_ssl(这点不说大家也知道,但为了明确:使用时请自担风险):
import urllib2, urllib2_ssl
opener = urllib2.build_opener(urllib2_ssl.HTTPSHandler(ca_certs='ca.pem'))
xml = opener.open('https://example.com/').read()
相关内容:在Python中安全地发起HTTPS请求。
使用 pycurl
:
c = pycurl.Curl()
c.setopt(pycurl.URL, "https://example.com?param1=val1¶m2=val2")
c.setopt(pycurl.HTTPGET, 1)
c.setopt(pycurl.CAINFO, 'ca.pem')
c.setopt(pycurl.SSL_VERIFYPEER, 1)
c.setopt(pycurl.SSL_VERIFYHOST, 2)
c.setopt(pycurl.SSLVERSION, 3)
c.setopt(pycurl.NOBODY, 1)
c.setopt(pycurl.NOSIGNAL, 1)
c.perform()
c.close()
要实现“证书固定”,需要为不同的域名提供不同的 'ca.pem'
文件。