मूल प्रमाणीकरण के साथ पायथन, HTTPS GET


90

पायथन का उपयोग करके मूल प्रमाणीकरण के साथ एक HTTPS GET करने की कोशिश कर रहा हूँ। अजगर के लिए बहुत नया हूँ और गाइड चीजों को करने के लिए अलग-अलग लाइब्रेरी का उपयोग करते हैं। (http.client, रिशेप्लिब और यूरलिब)। क्या कोई मुझे दिखा सकता है कि इसका काम कैसे हुआ? आप मानक पुस्तकालय का उपयोग करने के लिए कैसे कह सकते हैं?


2
क्या आप यह सुनिश्चित करना चाहते हैं कि प्रमाणपत्र मान्य है?
— एंड्रयू कॉक्स

1
की जाँच करें stackoverflow.com/questions/635113/... । ऐसा लगता है कि आप वास्तव में क्या देख रहे हैं।
— जियो

जवाबों:


122

पायथन 3 में निम्नलिखित काम करेंगे। मैं मानक पुस्तकालय से निचले स्तर के http.client का उपयोग कर रहा हूं । बुनियादी प्राधिकरण के विवरण के लिए rfc2617 के अनुभाग 2 को देखें। यह कोड प्रमाणपत्र को मान्य नहीं करेगा, लेकिन एक 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()  

5
requestविधि प्रलेखन [1] कहा गया है कि ISO-8859-1 ", HTTP के लिए डिफ़ॉल्ट चारसेट" "स्ट्रिंग्स के रूप में इनकोड"। इसलिए मैं "ASCII" के बजाय "ISO-8859-1" के साथ डीकोड करने का सुझाव देता हूं। [१] docs.python.org/3/library/…
— jgomo3

22
के बजाय चर का उपयोग करने के लिए b"username:password", का उपयोग करें bytes(username + ':' + password, "utf-8"):।
— kenorb

1
@ jgomo3: यह .decode("ascii")केवल bytes-> strरूपांतरण के लिए है। परिणाम b64encodeवैसे भी ASCII है।
— टॉरस्टेन ब्रॉन्गर

1
मेरे रक्षक। 4 घंटे के संघर्ष और मिस-डायरेक्शन का भार उठाने के बाद।
— कोनराड बी

मैं डिफ़ॉल्ट क्रेडेंशियल का उपयोग कैसे करूं? यदि यह कोड किसी अन्य सिस्टम में सही तरीके से काम करता है तो यह काम नहीं करेगा?
— अनंधु

93

पायथन की शक्ति का उपयोग करें और आसपास के सर्वश्रेष्ठ पुस्तकालयों में से एक पर झुकें: अनुरोध

import requests

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

चर आर (अनुरोधों की प्रतिक्रिया) में बहुत अधिक पैरामीटर हैं जो आप उपयोग कर सकते हैं। सबसे अच्छी बात यह है कि इंटरैक्टिव दुभाषिया में पॉप और इसके साथ खेलने के लिए, और / या अनुरोध डॉक्स पढ़ें ।

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'})

23

अपडेट: ओपी पायथन 3 का उपयोग करता है

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

अजगर 2.6 के लिए नीचे काम करता है:

मैं pycurlएक प्रक्रिया के लिए उत्पादन में बहुत अधिक उपयोग करता हूं जो प्रति दिन 10 मिलियन अनुरोधों के ऊपर होता है।

आपको पहले निम्नलिखित का आयात करना होगा।

import pycurl
import cStringIO
import base64

मूल प्रमाणीकरण शीर्षलेख के भाग में बेस 64 के रूप में एन्कोड किया गया उपयोगकर्ता नाम और पासवर्ड शामिल है।

headers = { 'Authorization' : 'Basic %s' % base64.b64encode("username:password") }

HTTP हेडर में आपको यह लाइन दिखाई देगी Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=। एन्कोडेड स्ट्रिंग आपके उपयोगकर्ता नाम और पासवर्ड के आधार पर बदल जाती है।

अब हमें अपने HTTP प्रतिक्रिया को लिखने और कर्ल कनेक्शन हैंडल के लिए जगह चाहिए।

response = cStringIO.StringIO()
conn = pycurl.Curl()

हम विभिन्न कर्ल विकल्प सेट कर सकते हैं। विकल्पों की पूरी सूची के लिए, इसे देखें । लिंक्ड डाक्यूमेंट 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.writeHTTP प्रतिक्रिया को संग्रहीत करने के लिए कॉल करें ।

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

ऐसा लगता है कि pyhthon 2.5 im के लिए 3 का उपयोग कर रहा है
— टॉम स्क्वायर्स

क्या आप आसान स्थापित या पाइप का उपयोग कर रहे हैं? क्या अजगर 3 के लिए pycurl पैकेज अनुपलब्ध है?
— ओकाज नाइट्स

एकplplib2 के साथ अद्यतन किया गया। यह अजगर के लिए उपलब्ध है 3.
— ओकाज नाइट्स

जो लोग नए हैं: उपरोक्त उदाहरण में एक बिंदु याद आ रहा है: "pycurl.HTTPHEADER" (मैं संपादित करता हूं लेकिन यह 1 वर्ण है और न्यूनतम 6 है)।
— ग्रीम विकस्टेड

ओपी ने कहा GET नहीं, POST
— C C

17

प्रमाणपत्र सत्यापन के साथ Python3 में मूल स्थिति को करने का एक सही तरीका urllib.requestहै।

ध्यान दें कि certifiअनिवार्य नहीं है। आप अपने ओएस बंडल (केवल * निक्स) का उपयोग कर सकते हैं या मोज़िला के सीए बंडल को स्वयं वितरित कर सकते हैं। या यदि आप जिस मेजबानों के साथ संवाद करते हैं, वे कुछ ही हैं, तो सीए सीए खुद को मेजबानों के सीए से फाइल करते हैं, जिससे एक और भ्रष्ट सीए द्वारा किए गए मित्म हमले का खतरा कम हो सकता है ।

#!/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())

यह भी खूब रही। सादे पाठ क्रेडेंशियल्स (HTTP मूल प्रामाणिक) भेजते समय प्रमाणपत्र सत्यापन महत्वपूर्ण है। आपको यह सुनिश्चित करने की आवश्यकता है कि आपकी TLS परत (HTTPS) सुरक्षित है, क्योंकि आप उस परत पर निर्भर हैं ताकि सुरक्षित रहें।
— चार

सही लगता है, लेकिन मेरे मामले में काम नहीं किया, यह ssl.SSLCertVerificationError की तरह त्रुटि फेंक रहा है: [एसएसएल: CERTIFICATE_VERIFY_FAILED] प्रमाणपत्र विफल रहा: स्थानीय मतदाता प्रमाणपत्र प्राप्त करने में असमर्थ (_ssl.c: 1056)
— neelmeg

मैंने सत्यापित परम और कुकीज़ परम के लिए एक वैध पीएम प्रमाणपत्र पारित करके यह पता लगाया।
— नीलमेग

1

केवल मानक मॉड्यूल और कोई मैनुअल हेडर एन्कोडिंग का उपयोग करना

... जो अभीष्ट और सबसे पोर्टेबल तरीका लगता है

अजगर urllib की अवधारणा विभिन्न प्रबंधकों / निदेशकों / संदर्भों में अनुरोध की कई विशेषताओं को समूहित करना है ... जो तब उनके भागों को संसाधित करते हैं:

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

0

कुछ मामूली सुधारों के साथ @AndrewCox के उत्तर के आधार पर:

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

ध्यान दें, आपको एन्कोडिंग सेट करना चाहिए यदि आप bytesइसके बजाय फ़ंक्शन का उपयोग करते हैं b""।


-1
requests.get(url, auth=requests.auth.HTTPBasicAuth(username=token, password=''))

यदि टोकन के साथ, पासवर्ड होना चाहिए ''।

इससे मेरा काम बनता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.