I am trying to login to a REST API using HTTP Basic Authentication but it is not working and giving the error
HTTP error 400: Bad Request
Here is my code:
import urllib.parse
import urllib.request
import urllib.response
# create an authorization handler
#auth_handler = urllib.request.HTTPPasswordMgrWithDefaultRealm()
auth_handler = urllib.request.HTTPBasicAuthHandler()
# Add the username and password.
# If we knew the realm, we could use it instead of None.
userName = "username"
passWord = "pass"
top_level_url = "http URL"
auth_handler.add_password(None, top_level_url, userName,passWord)
# create "opener" (OpenerDirector instance)
opener = urllib.request.build_opener(auth_handler)
# Install the opener.
# Now all calls to urllib.request.urlopen use our opener.
urllib.request.install_opener(opener)
# use the opener to fetch a URL
try:
result = opener.open(top_level_url)
#result = urllib.request.urlopen(top_level_url)
messages = result.read()
print (messages)
except IOError as e:
print (e)
You'll need to import the following first. Part of the basic authentication header consists of the username and password encoded as Base64. In the HTTP header you will see this line Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= . The encoded string changes depending on your username and password.
We can do HTTP basic authentication URL with @ in password. We have to pass the credentials appended with the URL. The username and password must be added with the format − https://username:password@URL.
Basic Auth:The client sends HTTP requests with the Authorization header that contains the word Basic, followed by a space and a base64-encoded(non-encrypted) string username: password. For example, to authorize as username / Pa$$w0rd the client would send. Note: Base64 encoding does not mean encryption or hashing!
The following python3 code will work:
import urllib.request
import base64
req = urllib.request.Request(download_url)
credentials = ('%s:%s' % (username, password))
encoded_credentials = base64.b64encode(credentials.encode('ascii'))
req.add_header('Authorization', 'Basic %s' % encoded_credentials.decode("ascii"))
with urllib.request.urlopen(req) as response, open(out_file_path, 'wb') as
out_file:
data = response.read()
out_file.write(data)
Updated for Python 3.x compatibility.
The requests library offers a far easier way of making this sort of request:
import requests
response = requests.get('http://service.example.com',
auth=requests.auth.HTTPBasicAuth(
'username', 'password'))
print(response.text)
In my own testing this works out fine, while a solution involving urllib.request
(like yours, or using the code verbatim from the examples in the documentation) will fail to send the Authentication:
header.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With