Ich versuche, ein HTTPS-GET mit grundlegender Authentifizierung unter Verwendung von Python durchzuführen. Ich bin sehr neu in Python und die Anleitungen scheinen verschiedene Bibliotheken zu verwenden, um Dinge zu tun. (http.client, httplib und urllib). Kann mir jemand zeigen, wie es geht? Wie können Sie die Standardbibliothek zur Verwendung anweisen?
python
python-3.x
Tom Squires
quelle
quelle
Antworten:
In Python 3 funktioniert Folgendes. Ich verwende den untergeordneten http.client aus der Standardbibliothek. Weitere Informationen zur Grundautorisierung finden Sie in Abschnitt 2 von rfc2617 . Dieser Code überprüft nicht, ob das Zertifikat gültig ist, stellt jedoch eine https-Verbindung her. Informationen dazu finden Sie in den http.client- Dokumenten.
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()
quelle
request
Methodendokumentation [1] wird erwähnt, dass "Strings als" ISO-8859-1 ", der Standardzeichensatz für HTTP, codiert sind. Daher empfehle ich, mit "ISO-8859-1" anstelle von "ASCII" zu dekodieren. [1] docs.python.org/3/library/…b"username:password"
:bytes(username + ':' + password, "utf-8")
..decode("ascii")
ist nur für diebytes
->str
Konvertierung. Das Ergebnis vonb64encode
ist sowieso nur ASCII.Nutzen Sie die Leistungsfähigkeit von Python und stützen Sie sich auf eine der besten Bibliotheken: Anfragen
import requests r = requests.get('https://my.website.com/rest/path', auth=('myusername', 'mybasicpass')) print(r.text)
Die Variable r (Anforderungsantwort) enthält viel mehr Parameter, die Sie verwenden können. Am besten gehen Sie in den interaktiven Interpreter und spielen damit herum und / oder lesen Anforderungsdokumente .
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'})
quelle
Update: OP verwendet Python 3. Fügen Sie also ein Beispiel mit httplib2 hinzu
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")
Das Folgende funktioniert für Python 2.6:
Ich verwende
pycurl
viel in der Produktion für einen Prozess, der mehr als 10 Millionen Anfragen pro Tag bearbeitet.Sie müssen zuerst Folgendes importieren.
import pycurl import cStringIO import base64
Ein Teil des grundlegenden Authentifizierungsheaders besteht aus dem Benutzernamen und dem Kennwort, die als Base64 codiert sind.
headers = { 'Authorization' : 'Basic %s' % base64.b64encode("username:password") }
Im HTTP-Header sehen Sie diese Zeile
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
. Die codierte Zeichenfolge ändert sich abhängig von Ihrem Benutzernamen und Passwort.Wir brauchen jetzt einen Ort, an den wir unsere HTTP-Antwort schreiben können, und ein Curl-Verbindungshandle.
Wir können verschiedene Lockenoptionen einstellen. Eine vollständige Liste der Optionen finden Sie hier . Die verknüpfte Dokumentation bezieht sich auf die libcurl-API, die Optionen ändern sich jedoch nicht für andere Sprachbindungen.
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)
Wenn Sie das Zertifikat nicht überprüfen müssen. Warnung: Dies ist unsicher. Ähnlich wie beim Laufen
curl -k
odercurl --insecure
.conn.setopt(pycurl.SSL_VERIFYPEER, False) conn.setopt(pycurl.SSL_VERIFYHOST, False)
Aufruf
cStringIO.write
zum Speichern der HTTP-Antwort.Wenn Sie eine POST-Anfrage stellen.
post_body = "foobar" conn.setopt(pycurl.POSTFIELDS, post_body)
Stellen Sie jetzt die eigentliche Anfrage.
Tun Sie etwas basierend auf dem HTTP-Antwortcode.
http_code = conn.getinfo(pycurl.HTTP_CODE) if http_code is 200: print response.getvalue()
quelle
Es folgt eine korrekte Methode zur grundlegenden Authentifizierung in Python3
urllib.request
mit Zertifikatüberprüfung.Beachten Sie, dass dies
certifi
nicht obligatorisch ist. Sie können Ihr Betriebssystem-Bundle (wahrscheinlich nur * nix) verwenden oder das CA-Bundle von Mozilla selbst verteilen . Wenn es sich bei den Hosts, mit denen Sie kommunizieren, nur um wenige handelt, verknüpfen Sie die CA-Datei selbst mit den CAs der Hosts, wodurch das Risiko eines MitM- Angriffs durch eine andere beschädigte CA verringert werden kann.#!/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())
quelle
Verwenden Sie nur Standardmodule und keine manuelle Header-Codierung
... was der beabsichtigte und tragbarste Weg zu sein scheint
Das Konzept von Python Urllib besteht darin, die zahlreichen Attribute der Anfrage in verschiedene Manager / Direktoren / Kontexte zu gruppieren ... die dann ihre Teile verarbeiten:
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())
quelle
Basierend auf der Antwort von @AndrewCox mit einigen geringfügigen Verbesserungen:
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()
Beachten Sie, dass Sie die Codierung festlegen sollten, wenn Sie die
bytes
Funktion anstelle von verwendenb""
.quelle
requests.get(url, auth=requests.auth.HTTPBasicAuth(username=token, password=''))
Wenn mit Token, sollte das Passwort sein
''
.Für mich geht das.
quelle