파이썬을 사용하여 기본 인증으로 HTTPS GET을 시도하고 있습니다. 나는 파이썬을 처음 접했고 가이드는 다른 라이브러리를 사용하여 일을하는 것 같습니다. (http.client, httplib 및 urllib). 누구든지 그 방법을 보여줄 수 있습니까? 표준 라이브러리에 사용을 어떻게 알릴 수 있습니까?
파이썬을 사용하여 기본 인증으로 HTTPS GET을 시도하고 있습니다. 나는 파이썬을 처음 접했고 가이드는 다른 라이브러리를 사용하여 일을하는 것 같습니다. (http.client, httplib 및 urllib). 누구든지 그 방법을 보여줄 수 있습니까? 표준 라이브러리에 사용을 어떻게 알릴 수 있습니까?
답변:
Python 3에서는 다음이 작동합니다. 표준 라이브러리 의 하위 수준 http.client 를 사용하고 있습니다. 또한 기본 인증에 대한 자세한 내용은 rfc2617의 섹션 2를 확인하십시오 . 이 코드는 인증서가 유효한지 확인하지 않지만 https 연결을 설정합니다. 이를 수행하는 방법에 대해서는 http.client 문서를 참조하십시오 .
from http.client import HTTPSConnection
from base64 import b64encode
#This sets up the https connection
c = HTTPSConnection("www.google.com")
#we need to base 64 encode it
#and then decode it to acsii as python 3 stores it as a byte string
userAndPass = b64encode(b"username:password").decode("ascii")
headers = { 'Authorization' : 'Basic %s' % userAndPass }
#then connect
c.request('GET', '/', headers=headers)
#get the response back
res = c.getresponse()
# at this point you could check the status etc
# this gets the page text
data = res.read()
request방법 문서 [1] ISO-8859-1 ", HTTP의 기본 문자 집합", "문자열로 인코딩된다"고 언급하고있다. 그래서 "ASCII"대신 "ISO-8859-1"로 디코딩하는 것이 좋습니다. [1] docs.python.org/3/library/…
b"username:password"하십시오 bytes(username + ':' + password, "utf-8")..
.decode("ascii")전용입니다 . 결과는 어쨌든 ASCII 전용입니다. bytesstrb64encode
Python의 힘을 사용하고 최고의 라이브러리 중 하나 인 요청 에 의지하십시오.
import requests
r = requests.get('https://my.website.com/rest/path', auth=('myusername', 'mybasicpass'))
print(r.text)
변수 r (응답 요청)에는 사용할 수있는 더 많은 매개 변수가 있습니다. 가장 좋은 방법은 인터랙티브 인터프리터에 들어가서 놀거나 요청 문서를 읽는 것 입니다.
ubuntu@hostname:/home/ubuntu$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> r = requests.get('https://my.website.com/rest/path', auth=('myusername', 'mybasicpass'))
>>> dir(r)
['__attrs__', '__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_content', '_content_consumed', 'apparent_encoding', 'close', 'connection', 'content', 'cookies', 'elapsed', 'encoding', 'headers', 'history', 'iter_content', 'iter_lines', 'json', 'links', 'ok', 'raise_for_status', 'raw', 'reason', 'request', 'status_code', 'text', 'url']
>>> r.content
b'{"battery_status":0,"margin_status":0,"timestamp_status":null,"req_status":0}'
>>> r.text
'{"battery_status":0,"margin_status":0,"timestamp_status":null,"req_status":0}'
>>> r.status_code
200
>>> r.headers
CaseInsensitiveDict({'x-powered-by': 'Express', 'content-length': '77', 'date': 'Fri, 20 May 2016 02:06:18 GMT', 'server': 'nginx/1.6.3', 'connection': 'keep-alive', 'content-type': 'application/json; charset=utf-8'})
업데이트 : OP는 Python 3을 사용 하므로 httplib2 를 사용하여 예제 추가
import httplib2
h = httplib2.Http(".cache")
h.add_credentials('name', 'password') # Basic authentication
resp, content = h.request("https://host/path/to/resource", "POST", body="foobar")
아래는 Python 2.6에서 작동합니다.
pycurl하루에 천만 건 이상의 요청을 처리하는 프로세스를 위해 프로덕션에서 많이 사용 합니다.
먼저 다음을 가져와야합니다.
import pycurl
import cStringIO
import base64
기본 인증 헤더의 일부는 Base64로 인코딩 된 사용자 이름과 비밀번호로 구성됩니다.
headers = { 'Authorization' : 'Basic %s' % base64.b64encode("username:password") }
HTTP 헤더에서이 줄을 볼 수 있습니다 Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=. 인코딩 된 문자열은 사용자 이름과 암호에 따라 변경됩니다.
이제 HTTP 응답을 작성할 장소와 curl 연결 핸들이 필요합니다.
response = cStringIO.StringIO()
conn = pycurl.Curl()
다양한 컬 옵션을 설정할 수 있습니다. 전체 옵션 목록 은이를 참조하십시오 . 링크 된 문서는 libcurl API 용이지만 다른 언어 바인딩에 대한 옵션은 변경되지 않습니다.
conn.setopt(pycurl.VERBOSE, 1)
conn.setopt(pycurlHTTPHEADER, ["%s: %s" % t for t in headers.items()])
conn.setopt(pycurl.URL, "https://host/path/to/resource")
conn.setopt(pycurl.POST, 1)
인증서를 확인할 필요가없는 경우. 경고 : 이것은 안전하지 않습니다. running curl -k또는 curl --insecure.
conn.setopt(pycurl.SSL_VERIFYPEER, False)
conn.setopt(pycurl.SSL_VERIFYHOST, False)
cStringIO.writeHTTP 응답 저장을 호출 합니다.
conn.setopt(pycurl.WRITEFUNCTION, response.write)
POST 요청을 할 때.
post_body = "foobar"
conn.setopt(pycurl.POSTFIELDS, post_body)
지금 실제 요청하십시오.
conn.perform()
HTTP 응답 코드에 따라 작업을 수행하십시오.
http_code = conn.getinfo(pycurl.HTTP_CODE)
if http_code is 200:
print response.getvalue()
인증서 유효성 검사를 사용 하여 Python3에서 기본 인증 을 수행하는 올바른 방법은 urllib.request다음과 같습니다.
즉주의 certifi의무가 아닙니다. OS 번들 (예 : * nix 전용)을 사용하거나 Mozilla의 CA 번들을 직접 배포 할 수 있습니다 . 또는 통신하는 호스트가 소수 인 경우 호스트의 CA에서 직접 CA 파일을 연결하면 다른 손상된 CA로 인한 MitM 공격 위험을 줄일 수 있습니다 .
#!/usr/bin/env python3
import urllib.request
import ssl
import certifi
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(certifi.where())
httpsHandler = urllib.request.HTTPSHandler(context = context)
manager = urllib.request.HTTPPasswordMgrWithDefaultRealm()
manager.add_password(None, 'https://domain.com/', 'username', 'password')
authHandler = urllib.request.HTTPBasicAuthHandler(manager)
opener = urllib.request.build_opener(httpsHandler, authHandler)
# Used globally for all urllib.request requests.
# If it doesn't fit your design, use opener directly.
urllib.request.install_opener(opener)
response = urllib.request.urlopen('https://domain.com/some/path')
print(response.read())
... 의도되고 가장 휴대 가능한 방법 인 것 같습니다.
python urllib의 개념은 요청의 수많은 속성을 다양한 관리자 / 디렉터 / 컨텍스트로 그룹화 한 다음 해당 부분을 처리하는 것입니다.
import urllib.request, ssl
# to avoid verifying ssl certificates
httpsHa = urllib.request.HTTPSHandler(context= ssl._create_unverified_context())
# setting up realm+urls+user-password auth
# (top_level_url may be sequence, also the complete url, realm None is default)
top_level_url = 'https://ip:port_or_domain'
# of the std managers, this can send user+passwd in one go,
# not after HTTP req->401 sequence
password_mgr = urllib.request.HTTPPasswordMgrWithPriorAuth()
password_mgr.add_password(None, top_level_url, "user", "password", is_authenticated=True)
handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
# create OpenerDirector
opener = urllib.request.build_opener(handler, httpsHa)
url = top_level_url + '/some_url?some_query...'
response = opener.open(url)
print(response.read())
@AndrewCox의 답변에 약간의 개선 사항이 있습니다.
from http.client import HTTPSConnection
from base64 import b64encode
client = HTTPSConnection("www.google.com")
user = "user_name"
password = "password"
headers = {
"Authorization": "Basic {}".format(
b64encode(bytes(f"{user}:{password}", "utf-8")).decode("ascii")
)
}
client.request('GET', '/', headers=headers)
res = client.getresponse()
data = res.read()
bytes대신 function 을 사용하는 경우 인코딩을 설정해야합니다 b"".