Basic Authentication with urllib3
Short Answer: urllib3 doesn't have a dedicated built-in function for basic authentication, but you can easily implement it using the Authorization
header with base64-encoded credentials.
How Basic Authentication Works
Basic authentication sends credentials in the HTTP Authorization
header using this format:
Authorization: Basic <base64-encoded-username:password>
Implementation Methods
Method 1: Manual Base64 Encoding
import urllib3
from base64 import b64encode
# Create a PoolManager instance
http = urllib3.PoolManager()
# Your credentials
username = 'your_username'
password = 'your_password'
# Encode credentials to base64
credentials = b64encode(f'{username}:{password}'.encode()).decode('utf-8')
# Make authenticated request
response = http.request(
'GET',
'https://api.example.com/protected',
headers={
'Authorization': f'Basic {credentials}'
}
)
print(f"Status: {response.status}")
print(f"Data: {response.data.decode('utf-8')}")
Method 2: Using urllib3.util.make_headers
import urllib3
from urllib3.util import make_headers
http = urllib3.PoolManager()
# Create basic auth headers automatically
headers = make_headers(basic_auth='username:password')
response = http.request(
'GET',
'https://api.example.com/protected',
headers=headers
)
print(response.data.decode('utf-8'))
Method 3: Reusable Function
import urllib3
from base64 import b64encode
def create_basic_auth_header(username, password):
"""Create a basic authentication header."""
credentials = b64encode(f'{username}:{password}'.encode()).decode('utf-8')
return {'Authorization': f'Basic {credentials}'}
# Usage
http = urllib3.PoolManager()
auth_headers = create_basic_auth_header('myuser', 'mypass')
response = http.request(
'POST',
'https://api.example.com/data',
headers=auth_headers,
body='{"data": "example"}',
headers={**auth_headers, 'Content-Type': 'application/json'}
)
Handling Authentication Errors
import urllib3
from urllib3.util import make_headers
http = urllib3.PoolManager()
try:
headers = make_headers(basic_auth='username:password')
response = http.request('GET', 'https://api.example.com/protected', headers=headers)
if response.status == 200:
print("Authentication successful!")
print(response.data.decode('utf-8'))
elif response.status == 401:
print("Authentication failed: Invalid credentials")
elif response.status == 403:
print("Authentication failed: Access forbidden")
else:
print(f"Request failed with status: {response.status}")
except urllib3.exceptions.HTTPError as e:
print(f"HTTP error occurred: {e}")
Security Best Practices
1. Always Use HTTPS
# ❌ Never do this - credentials sent in plain text
response = http.request('GET', 'http://api.example.com/protected', headers=headers)
# ✅ Always use HTTPS for authentication
response = http.request('GET', 'https://api.example.com/protected', headers=headers)
2. Store Credentials Securely
import os
from urllib3.util import make_headers
# ✅ Read credentials from environment variables
username = os.getenv('API_USERNAME')
password = os.getenv('API_PASSWORD')
if not username or not password:
raise ValueError("Missing authentication credentials")
headers = make_headers(basic_auth=f'{username}:{password}')
3. Handle Sensitive Data Properly
import urllib3
from base64 import b64encode
def secure_basic_auth_request(url, username, password):
"""Make an authenticated request with proper cleanup."""
try:
# Create credentials
credentials = b64encode(f'{username}:{password}'.encode()).decode('utf-8')
http = urllib3.PoolManager()
response = http.request(
'GET',
url,
headers={'Authorization': f'Basic {credentials}'}
)
return response
finally:
# Clear sensitive variables
credentials = None
username = None
password = None
Alternative: Using requests Library
For simpler basic authentication, consider using the requests
library:
import requests
from requests.auth import HTTPBasicAuth
# Much simpler with requests
response = requests.get(
'https://api.example.com/protected',
auth=HTTPBasicAuth('username', 'password')
)
print(response.text)
Summary
While urllib3 doesn't have a dedicated basic authentication function, you can implement it using:
- Manual base64 encoding with the
Authorization
header urllib3.util.make_headers()
utility function (recommended)- Custom helper functions for reusable authentication logic
Always use HTTPS and handle credentials securely when implementing basic authentication in production applications.