Reputation: 983
I'm currently authenticating with basic, following this tutorial:
import secrets
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials,
http_basic = HTTPBasic()
def authorize_basic(credentials: HTTPBasicCredentials = Depends(http_basic)):
correct_username = secrets.compare_digest(credentials.username, "test")
correct_password = secrets.compare_digest(credentials.password, "test")
if not (correct_username and correct_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Basic"},
)
@app.get("/auth/", dependencies=[Depends(authorize_basic)])
def auth():
return {"success": "true"}
How do I use HTTPDigest instead?
Upvotes: 4
Views: 2174
Reputation: 1731
I know this question was asked quite a while ago but this example from the FastAPI test suite shows how to do it.
You can rewrite the above example as follows:
import base64
import secrets
from fastapi import Depends, FastAPI, HTTPException, Security, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPDigest
http_digest = HTTPDigest()
app = FastAPI()
def authorize_digest(credentials: HTTPAuthorizationCredentials = Security(http_digest)):
# Credentials returns the token as string.
incoming_token = credentials.credentials
# Let's say you want to generate the digest token from username and pass.
expected_username = "test"
expected_password = "test"
# Digest tokens are encoded via base64 encoding algo.
expected_token = base64.standard_b64encode(
bytes(f"{expected_username}:{expected_password}", encoding="UTF-8"),
)
correct_token = secrets.compare_digest(
bytes(incoming_token, encoding="UTF-8"),
expected_token,
)
if not correct_token:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect digest token",
headers={"WWW-Authenticate": "Digest"},
)
@app.get("/auth/", dependencies=[Depends(authorize_digest)])
def auth():
return {"success": "true"}
You can get the token using your username and password from your shell (assuming you're using a Unix-y system):
python -c 'import base64; h = base64.urlsafe_b64encode(b"test:test"); print(h)'
This assumes that both your username and password are test
. It'll print the following:
b'dGVzdDp0ZXN0'
You can use this token and send a request to this API via curl:
curl -X 'GET' 'http://localhost:5000/auth/' \
-H 'accept: application/json' \
-H "Authorization: Digest dGVzdDp0ZXN0" \
-H 'Content-Type: application/json' \
This prints out the success response:
{"success":"true"}
Upvotes: 2