4 changed files with 129 additions and 0 deletions
@ -0,0 +1,30 @@ |
|||||
|
from typing import Optional |
||||
|
|
||||
|
from fastapi import FastAPI, HTTPException, Security, status |
||||
|
from fastapi.security import APIKeyHeader |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
API_KEY = "supersecret" |
||||
|
API_KEY_NAME = "X-API-Key" |
||||
|
|
||||
|
api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False) |
||||
|
|
||||
|
|
||||
|
async def get_api_key(api_key: Optional[str] = Security(api_key_header)) -> str: |
||||
|
if api_key is None: |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_403_FORBIDDEN, |
||||
|
detail="Not authenticated", |
||||
|
) |
||||
|
if api_key != API_KEY: |
||||
|
raise HTTPException( |
||||
|
status_code=status.HTTP_403_FORBIDDEN, |
||||
|
detail="Invalid API key", |
||||
|
) |
||||
|
return api_key |
||||
|
|
||||
|
|
||||
|
@app.get("/protected-route") |
||||
|
async def protected_route(api_key: str = Security(get_api_key)): |
||||
|
return {"message": "You are authorized"} |
||||
@ -0,0 +1,33 @@ |
|||||
|
import pytest |
||||
|
from fastapi.testclient import TestClient |
||||
|
|
||||
|
|
||||
|
@pytest.fixture(name="client") |
||||
|
def get_client() -> TestClient: |
||||
|
from docs_src.security.tutorial_api_key_header import app |
||||
|
|
||||
|
return TestClient(app) |
||||
|
|
||||
|
|
||||
|
def test_no_api_key(client: TestClient) -> None: |
||||
|
response = client.get("/protected-route") |
||||
|
assert response.status_code == 403, response.text |
||||
|
assert response.json() == {"detail": "Not authenticated"} |
||||
|
|
||||
|
|
||||
|
def test_invalid_api_key(client: TestClient) -> None: |
||||
|
response = client.get( |
||||
|
"/protected-route", |
||||
|
headers={"X-API-Key": "wrong"}, |
||||
|
) |
||||
|
assert response.status_code == 403, response.text |
||||
|
assert response.json() == {"detail": "Invalid API key"} |
||||
|
|
||||
|
|
||||
|
def test_valid_api_key(client: TestClient) -> None: |
||||
|
response = client.get( |
||||
|
"/protected-route", |
||||
|
headers={"X-API-Key": "supersecret"}, |
||||
|
) |
||||
|
assert response.status_code == 200, response.text |
||||
|
assert response.json() == {"message": "You are authorized"} |
||||
Loading…
Reference in new issue