How SSL/TLS + Authentication (BSAIC Auth or Bearer Token) works in REST APIs with example
Purpose: Encrypts everything between client and server.
What it protects:
Request headers (including Authorization for Basic Auth or Bearer tokens)
Request body / JSON payload
URL query parameters
Effect: Even if someone is sniffing your network, they cannot read or modify the data.
Note: TLS does not verify who the client is; it just protects the channel.
2. Authentication → Verifies who the client is
TLS + authentication are separate layers:
Method Role
Basic Auth Checks username + password (server verifies identity)
OAuth2 / Bearer Checks access token issued by auth server; validates client and permissions
TLS client certs (Optional) server can verify client identity via certificate
So, authentication ensures only valid clients can access resources, while TLS ensures no one can eavesdrop or tamper with that authentication info.
3. Putting it together
Client connects via HTTPS (TLS) → secure encrypted channel
Client sends Basic Auth credentials or OAuth2 token → headers encrypted by TLS
Server decrypts and authenticates the client
Server responds over the same encrypted channel → response is safe from eavesdroppers
TLS = transport security
Auth (Basic / OAuth2) = client verification
1. Basic Auth over HTTPS
curl -k -u username:password https://127.0.0.1:8000/secure-data
-u username:password → sets Authorization: Basic <base64> header
-k → allows self-signed certificate
Over HTTPS, the Authorization header is fully encrypted.
2. OAuth2 Bearer Token over HTTPS
curl -k -H "Authorization: Bearer <your-token>" https://127.0.0.1:8000/secure-data
<your-token> = token obtained from /token endpoint
Header Authorization: Bearer <token> is encrypted by HTTPS
We can use Python (FastAPI) for simplicity.
Step 1: Generate a Self-Signed Certificate
# Create a folder for certificates
mkdir certs && cd certs
# Generate key and self-signed cert valid for 365 days
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
key.pem → private key
cert.pem → public certificate
-nodes → prevents password prompt (useful for local dev)
Step 2: Create a Simple FastAPI Application
Install dependencies:
pip install fastapi uvicorn python-jose[cryptography]
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
# Secret key for signing tokens (in real apps, keep secret!)
SECRET_KEY = "mysecret"
ALGORITHM = "HS256"
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# Dummy user validation
def verify_token(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid token")
return username
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
@app.post("/token")
def login(username: str):
# Return a JWT token for testing
token = jwt.encode({"sub": username}, SECRET_KEY, algorithm=ALGORITHM)
return {"access_token": token, "token_type": "bearer"}
@app.get("/secure-data")
def secure_endpoint(user: str = Depends(verify_token)):
return {"message": f"Hello {user}, this is protected data!"}
Step 3: Run FastAPI with HTTPS (Self-Signed Cert)
uvicorn app:app --host 0.0.0.0 --port 8000 --ssl-keyfile certs/key.pem --ssl-certfile certs/cert.pem
INFO: Started server process [25494]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on https://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: 172.27.70.130:40004 - "POST /token?username=mohan HTTP/1.1" 200 OK
INFO: 172.27.70.130:45190 - "GET /secure-data HTTP/1.1" 401 Unauthorized
INFO: 172.27.70.130:54832 - "GET /secure-data HTTP/1.1" 200 OK
Step 4: Test API with OAuth2 Token
tav-suse-mgr:~ # curl -s -k -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0dXNlciIsImlhdCI6MTc1OTM5NjA3NSwiZXhwIjoxNzU5Mzk5Njc1fQ.iL5Xul0zj9Jggq3v5sZ6Z9Pf4zYnx0WXmOQDJaWYNr" https://172.27.64.9:8000/secure-data | jq .
{
"detail": "Invalid token"
}
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtb2hhbiIsImlhdCI6MTc1OTM5NzE4NSwiZXhwIjoxNzU5NDAwNzg1fQ.mBX4JnFyBIOTvKXAno4lglP-5wIt3-VBndjNMGbIg6A",
"token_type": "bearer"
}
tav-suse-mgr:~ # curl -s -k -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtb2hhbiIsImlhdCI6MTc1OTM5NzE4NSwiZXhwIjoxNzU5NDAwNzg1fQ.mBX4JnFyBIOTvKXAno4lglP-5wIt3-VBndjNMGbIg6A" https://172.27.64.9:8000/secure-data | jq .
{
"message": "Hello mohan, this is protected data!"
}
Comments
Post a Comment