Bearer Tokens — The Standard Format for Token-Based API Authentication
In this tutorial, you will learn about Bearer Tokens. We cover key concepts, practical examples, and best practices to help you master this topic.
Bearer token authentication uses the Authorization: Bearer <token> header, the standard format for transmitting access tokens in HTTP API requests.
What You'll Learn
How Bearer tokens work, the token format, security considerations, and how to implement Bearer token validation on the server.
Why It Matters
The Bearer token scheme is the standard for API token authentication. OAuth2, JWT, and most modern auth systems use the Authorization: Bearer header. Understanding Bearer tokens is essential for working with any modern API.
Real-World Use
GitHub API uses Authorization: Bearer ghp_..., Stripe uses Authorization: Bearer sk_live_..., and Google APIs use Authorization: Bearer ya29.... Every major API platform supports Bearer tokens.
flowchart LR
A["Client"] -->|"Request\nAuthorization: Bearer "| B["API Server"]
B -->|"Extract token"| C["Token Validator"]
C -->|"Valid"| D["Process Request\n200 OK"]
C -->|"Invalid/Expired"| 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
Bearer Token Format
Authorization: Bearer <token-value>
The token value can be any format — JWT, opaque string, reference token. The server determines how to validate it. The word "Bearer" means "the bearer of this token has access."
Token Types That Use Bearer Scheme
| Type | Format | Validation |
|---|---|---|
| JWT | Three base64 parts separated by dots | Verify signature, check claims |
| Opaque Token | Random string | Look up in server store |
| OAuth2 Access Token | Depends on provider | Introspect with authorization server |
| API Key | Static key string | Look up in key database |
Code Example: Bearer Token Middleware
from flask import Flask, request, jsonify
import jwt
app = Flask(__name__)
SECRET = "your-secret"
AUTHORIZATION_PREFIX = "Bearer "
def require_bearer_token(f):
def wrapper(*args, **kwargs):
auth_header = request.headers.get("Authorization", "")
# Validate format
if not auth_header.startswith(AUTHORIZATION_PREFIX):
return jsonify({
"error": "Unauthorized",
"message": "Authorization header must use Bearer scheme"
}), 401
token = auth_header[len(AUTHORIZATION_PREFIX):]
if not token:
return jsonify({"error": "Empty token"}), 401
# Validate token — implementation varies by token type
try:
payload = jwt.decode(token, SECRET, algorithms=["HS256"])
request.user = payload
except jwt.InvalidTokenError as e:
return jsonify({
"error": "Invalid token",
"detail": str(e)
}), 401
return f(*args, **kwargs)
wrapper.__name__ = f.__name__
return wrapper
@app.route("/api/data")
@require_bearer_token
def get_data():
return jsonify({
"data": "protected",
"user": request.user.get("sub")
})
if __name__ == "__main__":
app.run()
Code Example: Client Sending Bearer Token
import requests
token = "eyJhbGciOiJIUzI1NiIs..."
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.get(
"https://api.example.com/data",
headers=headers
)
print(f"Status: {response.status_code}")
print(response.json())
Code Example: Bearer Token with OAuth2 Introspection
import requests
def introspect_token(token):
response = requests.post(
"https://auth.example.com/introspect",
data={"token": token},
auth=("client_id", "client_secret")
)
return response.json()
@app.route("/api/data")
def get_data():
auth = request.headers.get("Authorization", "")
token = auth[7:] if auth.startswith("Bearer ") else None
if not token:
return jsonify({"error": "Missing token"}), 401
info = introspect_token(token)
if not info.get("active"):
return jsonify({"error": "Token inactive"}), 401
return jsonify({"data": "protected", "scope": info.get("scope")})
Common Mistakes
1. Not Validating the "Bearer " Prefix
Some servers split on space and take the second part. Always validate the prefix to reject malformed headers.
2. Trimming the Token
Bearer tokens are case-sensitive. Do not change the casing or trim characters. Pass the token as-is.
3. Logging Tokens
Never log Authorization headers. Tokens are credentials. If logs are breached, all tokens are exposed.
4. Using Query Parameters Instead of Headers
Passing access_token=xxx in the URL exposes the token in logs and history. Always use the Authorization header.
5. Confusing Bearer with Basic
Authorization: Bearer <token> is for tokens. Authorization: Basic <credentials> is for username:password. Do not mix them.
Practice Questions
- What is the full format of the Bearer token header?
- Why is it called a "Bearer" token?
- What is the difference between Bearer tokens and Basic Auth?
- Can Bearer tokens be used with query parameters?
- How should a server respond to a missing Bearer token?
Answers:
Authorization: Bearer <token-value>— the word Bearer followed by a space and the token.- "Bearer" means possession of the token grants access. Whoever "bears" (carries) the token can access the resource.
- Bearer uses tokens (JWT, opaque) while Basic Auth uses username:password. Bearer is more secure and flexible.
- Some APIs support
access_tokenas query parameter for backward compatibility, but headers are preferred for security. - Return 401 Unauthorized with
WWW-Authenticate: Bearerheader indicating the required auth scheme.
Challenge: Implement a Bearer token authentication system that supports both JWT and opaque tokens. The server should detect the token type and validate accordingly.
FAQ
Mini Project
Build a Flask middleware that validates Bearer tokens from the Authorization header, supports both JWT and opaque token types, returns proper 401 responses with WWW-Authenticate headers, and never logs token values.
What's Next
Now learn about specific OAuth2 grant types, starting with Client Credentials Grant for machine-to-machine authentication.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro