Python, HTTPS GET с базовой аутентификацией

Я пытаюсь выполнить HTTPS GET с базовой аутентификацией с помощью python. Я очень новичок в python, и гиды, похоже, используют разные библиотеки, чтобы делать что-то. (http.client, httplib и urllib). Может ли кто-нибудь показать мне, как это делается? Как вы можете указать стандартную библиотеку?

Ответ 1

В Python 3 будет работать следующее. Я использую нижний уровень http.client из стандартной библиотеки. Также ознакомьтесь с разделом 2 rfc2617 для получения подробной информации о базовой авторизации. Этот код не проверяет подлинность сертификата, но настроит соединение 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()  

Ответ 2

Обновление: 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 много в производстве для процесса, который делает более 10 миллионов запросов в день.

Вам нужно сначала импортировать следующее.

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()

Мы можем установить различные варианты завивки. Для полного списка опций см. Это. Связанная документация предназначена для API libcurl, но параметры не изменяются для других языковых привязок.

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)

Если вам не нужно проверять сертификат. Предупреждение: Это небезопасно. Подобно запуску curl -k или curl --insecure.

conn.setopt(pycurl.SSL_VERIFYPEER, False)
conn.setopt(pycurl.SSL_VERIFYHOST, False)

Вызовите cStringIO.write для хранения ответа HTTP.

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()

Ответ 3

Используйте силу Python и опирайтесь на одну из лучших библиотек: requests

import requests

r = requests.get('https://my.website.com/rest/path', auth=('myusername', 'mybasicpass'))
print(r.text)

Переменная r (запрос ответа) имеет гораздо больше параметров, которые вы можете использовать. Лучше всего появиться в интерактивном интерпретаторе и поиграть с ним и/или прочитать requests docs.

[email protected]:/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'})

Ответ 4

Правильный способ сделать basic auth в Python3 urllib.request с подтверждением сертификата.

Обратите внимание, что certifi не является обязательным. Вы можете использовать комплект вашей ОС (скорее всего, только * nix) или самостоятельно распределить Mozilla CA Bundle. Или, если хосты, с которыми вы общаетесь, - это всего лишь несколько, соедините 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())