Estou tentando fazer um HTTPS GET com autenticação básica usando python. Sou muito novo em python e os guias parecem usar diferentes bibliotecas para fazer as coisas. (http.client, httplib e urllib). Alguém pode me mostrar como é feito? Como você pode informar a biblioteca padrão para usar?
python
python-3.x
Tom Squires
fonte
fonte
Respostas:
No Python 3, o seguinte funcionará. Estou usando o http.client de nível inferior da biblioteca padrão. Verifique também a seção 2 do rfc2617 para obter detalhes sobre a autorização básica. Este código não verificará se o certificado é válido, mas configurará uma conexão https. Veja a documentação http.client sobre como fazer isso.
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()
fonte
request
documentação do método [1] menciona que "Strings são codificados como" ISO-8859-1 ", o conjunto de caracteres padrão para HTTP". Portanto, sugiro decodificar com "ISO-8859-1" em vez de "ASCII". [1] docs.python.org/3/library/…b"username:password"
, use:bytes(username + ':' + password, "utf-8")
..decode("ascii")
é apenas para a conversãobytes
->str
. O resultado deb64encode
é somente ASCII de qualquer maneira.Use o poder do Python e confie em uma das melhores bibliotecas: solicitações
import requests r = requests.get('https://my.website.com/rest/path', auth=('myusername', 'mybasicpass')) print(r.text)
A variável r (solicita resposta) tem muito mais parâmetros que você pode usar. O melhor é ir até o intérprete interativo e brincar com ele e / ou ler os documentos das solicitações .
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'})
fonte
Atualização: OP usa Python 3. Então, adicionando um exemplo usando 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")
O seguinte funciona para python 2.6:
Eu uso
pycurl
muito na produção para um processo que faz mais de 10 milhões de solicitações por dia.Você precisará importar o seguinte primeiro.
import pycurl import cStringIO import base64
Parte do cabeçalho de autenticação básica consiste no nome de usuário e senha codificados como Base64.
headers = { 'Authorization' : 'Basic %s' % base64.b64encode("username:password") }
No cabeçalho HTTP, você verá esta linha
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
. A string codificada muda dependendo do seu nome de usuário e senha.Agora precisamos de um local para escrever nossa resposta HTTP e um identificador de conexão curl.
Podemos definir várias opções de ondulação. Para uma lista completa de opções, veja isto . A documentação vinculada é para a API libcurl, mas as opções não mudam para outras ligações de linguagem.
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)
Se você não precisa verificar o certificado. Aviso: isso é inseguro. Semelhante a correr
curl -k
oucurl --insecure
.conn.setopt(pycurl.SSL_VERIFYPEER, False) conn.setopt(pycurl.SSL_VERIFYHOST, False)
Chame
cStringIO.write
para armazenar a resposta HTTP.Quando você está fazendo uma solicitação POST.
post_body = "foobar" conn.setopt(pycurl.POSTFIELDS, post_body)
Faça o pedido real agora.
Faça algo com base no código de resposta HTTP.
http_code = conn.getinfo(pycurl.HTTP_CODE) if http_code is 200: print response.getvalue()
fonte
Uma maneira correta de fazer autenticação básica em Python3
urllib.request
Segue com validação de certificado.Observe que
certifi
não é obrigatório. Você pode usar o pacote do seu sistema operacional (provavelmente apenas * nix) ou distribuir o pacote CA da Mozilla por conta própria. Ou, se os hosts com os quais você se comunica são apenas alguns, concatene você mesmo o arquivo CA das CAs dos hosts, o que pode reduzir o risco de ataque MitM causado por outra CA corrompida.#!/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())
fonte
usando apenas módulos padrão e nenhuma codificação manual de cabeçalho
... que parece ser a forma pretendida e mais portátil
o conceito de python urllib é agrupar os diversos atributos da solicitação em vários gerentes / diretores / contextos ... que então processam suas partes:
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())
fonte
Com base na resposta de @AndrewCox com algumas pequenas melhorias:
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()
Observe, você deve definir a codificação se usar
bytes
função em vez deb""
.fonte
requests.get(url, auth=requests.auth.HTTPBasicAuth(username=token, password=''))
Se for com token, a senha deve ser
''
.Funciona para mim.
fonte