J'essaie de faire un HTTPS GET avec une authentification de base en utilisant python. Je suis très nouveau en python et les guides semblent utiliser différentes bibliothèques pour faire les choses. (http.client, httplib et urllib). Quelqu'un peut-il me montrer comment c'est fait? Comment pouvez-vous dire à la bibliothèque standard d'utiliser?
python
python-3.x
Tom Squires
la source
la source
Réponses:
Dans Python 3, ce qui suit fonctionnera. J'utilise le niveau inférieur http.client de la bibliothèque standard. Consultez également la section 2 de la rfc2617 pour plus de détails sur l'autorisation de base. Ce code ne vérifiera pas la validité du certificat, mais établira une connexion https. Consultez la documentation http.client pour savoir comment procéder.
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()
la source
request
documentation de la méthode [1] mentionne que "les chaînes sont encodées comme" ISO-8859-1 ", le jeu de caractères par défaut pour HTTP". Je suggère donc de décoder avec "ISO-8859-1" au lieu de "ASCII". [1] docs.python.org/3/library/…b"username:password"
, utilisez:bytes(username + ':' + password, "utf-8")
..decode("ascii")
n'est que pour la conversionbytes
->str
. Le résultat deb64encode
est de toute façon ASCII uniquement.Utilisez la puissance de Python et appuyez-vous sur l'une des meilleures bibliothèques du marché: les requêtes
import requests r = requests.get('https://my.website.com/rest/path', auth=('myusername', 'mybasicpass')) print(r.text)
La variable r (demande de réponse) a beaucoup plus de paramètres que vous pouvez utiliser. La meilleure chose à faire est de faire un saut dans l'interpréteur interactif et de jouer avec, et / ou de lire les documents des demandes .
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'})
la source
Mise à jour: OP utilise Python 3. Ajout d'un exemple utilisant 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")
Ce qui suit fonctionne pour python 2.6:
J'utilise
pycurl
beaucoup en production pour un processus qui fait plus de 10 millions de demandes par jour.Vous devrez d'abord importer les éléments suivants.
import pycurl import cStringIO import base64
Une partie de l'en-tête d'authentification de base se compose du nom d'utilisateur et du mot de passe codés en Base64.
headers = { 'Authorization' : 'Basic %s' % base64.b64encode("username:password") }
Dans l'en-tête HTTP, vous verrez cette ligne
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
. La chaîne codée change en fonction de votre nom d'utilisateur et de votre mot de passe.Nous avons maintenant besoin d'un emplacement pour écrire notre réponse HTTP et d'un handle de connexion curl.
Nous pouvons définir diverses options de curl. Pour une liste complète des options, voir ceci . La documentation liée concerne l'API libcurl, mais les options ne changent pas pour les autres liaisons de langage.
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)
Si vous n'avez pas besoin de vérifier le certificat. Avertissement: ce n'est pas sûr. Similaire à exécuter
curl -k
oucurl --insecure
.conn.setopt(pycurl.SSL_VERIFYPEER, False) conn.setopt(pycurl.SSL_VERIFYHOST, False)
Appel
cStringIO.write
pour stocker la réponse HTTP.Lorsque vous faites une demande POST.
post_body = "foobar" conn.setopt(pycurl.POSTFIELDS, post_body)
Faites la demande réelle maintenant.
Faites quelque chose en fonction du code de réponse HTTP.
http_code = conn.getinfo(pycurl.HTTP_CODE) if http_code is 200: print response.getvalue()
la source
Une manière correcte de faire une authentification de base dans Python3
urllib.request
avec la validation de certificat suit.Notez que ce
certifi
n'est pas obligatoire. Vous pouvez utiliser votre bundle OS (probablement * nix uniquement) ou distribuer vous-même le bundle CA de Mozilla . Ou si les hôtes avec lesquels vous communiquez ne sont que quelques-uns, concaténez vous-même le fichier CA à partir des CA des hôtes, ce qui peut réduire le risque d' attaque MitM causée par une autre CA corrompue.#!/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())
la source
en utilisant uniquement des modules standard et pas de codage d'en-tête manuel
... ce qui semble être le moyen prévu et le plus portable
le concept de python urllib est de regrouper les nombreux attributs de la requête en différents managers / directeurs / contextes ... qui traitent ensuite leurs parties:
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())
la source
Basé sur la réponse de @AndrewCox avec quelques améliorations mineures:
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()
Remarque, vous devez définir l'encodage si vous utilisez la
bytes
fonction au lieu deb""
.la source
requests.get(url, auth=requests.auth.HTTPBasicAuth(username=token, password=''))
Si avec un jeton, le mot de passe doit être
''
.Ça marche pour moi.
la source