Saya mencoba melakukan HTTPS GET dengan otentikasi dasar menggunakan python. Saya sangat baru mengenal python dan panduan tampaknya menggunakan perpustakaan yang berbeda untuk melakukan sesuatu. (http.client, httplib, dan urllib). Adakah yang bisa menunjukkan kepada saya bagaimana ini dilakukan? Bagaimana Anda bisa memberitahu perpustakaan standar untuk digunakan?
python
python-3.x
Tom Squires
sumber
sumber
Jawaban:
Dengan Python 3 berikut ini akan bekerja. Saya menggunakan http.client tingkat yang lebih rendah dari perpustakaan standar. Lihat juga bagian 2 dari rfc2617 untuk detail otorisasi dasar. Kode ini tidak akan memeriksa apakah sertifikat valid, tetapi akan menyiapkan koneksi https. Lihat dokumentasi http.client tentang cara melakukannya.
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()
sumber
request
metode dokumentasi [1] menyebutkan bahwa "String dikodekan sebagai "ISO-8859-1", charset default untuk HTTP". Jadi saya sarankan untuk memecahkan kode dengan "ISO-8859-1" daripada "ASCII". [1] docs.python.org/3/library/…b"username:password"
, gunakan:bytes(username + ':' + password, "utf-8")
..decode("ascii")
Hanya untukbytes
->str
konversi. Hasilnyab64encode
adalah hanya ASCII.Gunakan kekuatan Python dan bersandar pada salah satu perpustakaan terbaik di sekitar: permintaan
import requests r = requests.get('https://my.website.com/rest/path', auth=('myusername', 'mybasicpass')) print(r.text)
Variabel r (respon permintaan) memiliki lebih banyak parameter yang dapat Anda gunakan. Hal terbaik adalah masuk ke interpreter interaktif dan bermain-main dengannya, dan / atau membaca dokumen permintaan .
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'})
sumber
Pembaruan: OP menggunakan Python 3. Jadi menambahkan contoh menggunakan 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")
Di bawah ini berfungsi untuk python 2.6:
Saya menggunakan
pycurl
banyak hal dalam produksi untuk proses yang menghasilkan lebih dari 10 juta permintaan per hari.Anda harus mengimpor yang berikut ini terlebih dahulu.
import pycurl import cStringIO import base64
Bagian dari header otentikasi dasar terdiri dari nama pengguna dan kata sandi yang dikodekan sebagai Base64.
headers = { 'Authorization' : 'Basic %s' % base64.b64encode("username:password") }
Di header HTTP Anda akan melihat baris ini
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
. Perubahan string yang disandikan tergantung pada nama pengguna dan kata sandi Anda.Kami sekarang membutuhkan tempat untuk menulis tanggapan HTTP kami dan pegangan koneksi curl.
Kami dapat mengatur berbagai opsi curl. Untuk daftar lengkap opsi, lihat ini . Dokumentasi terkait adalah untuk libcurl API, tetapi opsinya tidak berubah untuk binding bahasa lain.
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)
Jika Anda tidak perlu memverifikasi sertifikat. Peringatan: Ini tidak aman. Mirip dengan lari
curl -k
ataucurl --insecure
.conn.setopt(pycurl.SSL_VERIFYPEER, False) conn.setopt(pycurl.SSL_VERIFYHOST, False)
Panggilan
cStringIO.write
untuk menyimpan respons HTTP.Saat Anda membuat permintaan POST.
post_body = "foobar" conn.setopt(pycurl.POSTFIELDS, post_body)
Buat permintaan sebenarnya sekarang.
Lakukan sesuatu berdasarkan kode respons HTTP.
http_code = conn.getinfo(pycurl.HTTP_CODE) if http_code is 200: print response.getvalue()
sumber
Berikut cara yang benar untuk melakukan autentikasi dasar
urllib.request
dengan Python3 dengan validasi sertifikat.Perhatikan bahwa
certifi
itu tidak wajib. Anda dapat menggunakan bundel OS Anda (kemungkinan hanya * nix) atau mendistribusikan sendiri Bundel CA Mozilla . Atau jika host yang Anda ajak berkomunikasi hanya sedikit, gabungkan file CA Anda dari CA host, yang dapat mengurangi risiko serangan MitM yang disebabkan oleh CA lain yang korup.#!/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())
sumber
hanya menggunakan modul standar dan tidak ada pengkodean header manual
... yang tampaknya merupakan cara yang paling diinginkan dan paling portabel
konsep python urllib adalah mengelompokkan berbagai atribut permintaan ke dalam berbagai manajer / direktur / konteks ... yang kemudian memproses bagian-bagiannya:
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())
sumber
Berdasarkan jawaban @AndrewCox dengan beberapa perbaikan kecil:
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()
Catatan, Anda harus menyetel encoding jika Anda menggunakan
bytes
fungsi, bukanb""
.sumber
requests.get(url, auth=requests.auth.HTTPBasicAuth(username=token, password=''))
Jika dengan token, kata sandi harus
''
.Ini bekerja untuk saya.
sumber