HTTP Basic Authentication — Simple API Auth with Base64 Credentials
In this tutorial, you will learn about HTTP Basic Authentication. We cover key concepts, practical examples, and best practices to help you master this topic.
HTTP Basic Authentication sends a username and password encoded in Base64 via the Authorization header, offering the simplest authentication mechanism for API access.
What You'll Learn
How HTTP Basic Auth works, how to implement it on the server, its security limitations, and when it is appropriate to use in production.
Why It Matters
HTTP Basic Auth is the simplest authentication method supported by virtually every HTTP client and server. Understanding it helps you work with legacy systems, internal tools, and development environments.
Real-World Use
Internal admin dashboards, development API endpoints, IoT device configuration APIs, and legacy enterprise systems often use HTTP Basic Auth because of its simplicity and universal client support.
flowchart LR
A["Client"] -->|"GET /api/resource"| B["Server"]
B -->|"401 Unauthorized\nWWW-Authenticate: Basic"| A
A -->|"Authorization: Basic base64(user:pass)"| B
B -->|"Verify credentials"| C["User Database"]
C -->|"Valid"| D["200 OK + Data"]
C -->|"Invalid"| E["401 Unauthorized"]
style A fill:#dbeafe,stroke:#2563eb
style B fill:#fef3c7,stroke:#d97706
style D fill:#dcfce7,stroke:#16a34a
style E fill:#fecaca,stroke:#dc2626
How HTTP Basic Auth Works
The client sends a username and password joined by a colon (username:password) and encoded in Base64. The server decodes this and verifies the credentials.
Important: Base64 is not encryption — it is encoding. Anyone who intercepts the header can decode it immediately. HTTPS must be used to protect Basic Auth in transit.
Format
Authorization: Basic base64(username:password)
Example: For username admin and password secret123, the string admin:secret123 becomes YWRtaW46c2VjcmV0MTIz in Base64.
Authorization: Basic YWRtaW46c2VjcmV0MTIz
Code Example: Server Implementation
from flask import Flask, request, jsonify
import base64
app = Flask(__name__)
USERS = {"admin": "secret123", "api-user": "api-pass"}
def check_basic_auth(auth_header):
if not auth_header or not auth_header.startswith("Basic "):
return None
try:
decoded = base64.b64decode(auth_header[6:]).decode("utf-8")
username, password = decoded.split(":", 1)
if USERS.get(username) == password:
return username
except Exception:
pass
return None
@app.route("/api/status")
def get_status():
auth = request.headers.get("Authorization")
user = check_basic_auth(auth)
if not user:
return jsonify({"error": "Unauthorized"}), 401
return jsonify({"status": "ok", "user": user})
if __name__ == "__main__":
app.run()
Expected output:
$ curl -u admin:secret123 http://localhost:5000/api/status
{"status":"ok","user":"admin"}
$ curl http://localhost:5000/api/status
{"error":"Unauthorized"}
Code Example: Client-Side with curl
# curl handles Base64 encoding automatically with -u flag
curl -u admin:secret123 https://api.example.com/data
# Manual header equivalent
echo -n "admin:secret123" | base64
# Output: YWRtaW46c2VjcmV0MTIz
curl -H "Authorization: Basic YWRtaW46c2VjcmV0MTIz" https://api.example.com/data
Code Example: Client-Side with Python
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
"https://api.example.com/data",
auth=HTTPBasicAuth("admin", "secret123")
)
print(response.status_code) # 200
print(response.json())
Common Mistakes
1. Thinking Base64 Is Encryption
Base64 is encoding, not encryption. Anyone can decode YWRtaW46c2VjcmV0MTIz to admin:secret123 in seconds. Always use HTTPS.
2. Not Including the Space After "Basic"
The Authorization header must be Basic <token> with a space. Basic<token> without space will be rejected.
3. Using Basic Auth Without HTTPS
Without HTTPS, credentials are sent in plain text (encoded but not encrypted). Network sniffing tools like Wireshark can capture them.
4. Storing Passwords in Plain Text
If your server stores passwords in plain text to compare with Basic Auth, a database breach exposes all credentials. Hash passwords even for Basic Auth.
5. Using Basic Auth for User-Facing Apps
Basic Auth sends credentials with every request — the browser caches them permanently. Logging out requires closing the browser. Use session-based or token auth for user apps.
Practice Questions
- How does HTTP Basic Auth encode credentials?
- Why must HTTP Basic Auth always be used with HTTPS?
- What HTTP status code does the server return when Basic Auth fails?
- How does the server challenge a client to use Basic Auth?
- Is HTTP Basic Auth suitable for a public web application?
Answers:
- It joins username and password with a colon and encodes the result in Base64.
- Base64 is easily decoded. HTTPS encrypts the entire request, protecting credentials in transit.
- 401 Unauthorized, with a
WWW-Authenticate: Basicheader. - The server returns 401 with
WWW-Authenticate: Basic realm="Restricted"header, prompting the browser to show a login dialog. - No — Basic Auth provides no logout mechanism, no session management, and sends credentials with every request. Use token-based auth instead.
Challenge: Implement a middleware function that wraps a Flask route with HTTP Basic Auth, allowing you to protect multiple routes with @basic_auth_required decorator.
FAQ
Mini Project
Build a Flask application that protects multiple routes with HTTP Basic Auth, uses a dictionary of users, and returns appropriate 401 responses with WWW-Authenticate headers.
What's Next
Now learn HTTP Digest Authentication which improves on Basic Auth by hashing credentials before transmission.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro