From 0f07f42e3f9bf2fee183bd39cb2aa8e4737bd50f Mon Sep 17 00:00:00 2001 From: Esteban3010 Date: Tue, 18 Nov 2025 21:38:49 -0500 Subject: [PATCH 1/2] Add API key header security example and docs --- docs/en/docs/tutorial/security/index.md | 33 +++++++++++++++++++ docs/es/docs/tutorial/security/index.md | 33 +++++++++++++++++++ docs_src/security/tutorial_api_key_header.py | 30 +++++++++++++++++ .../test_tutorial_api_key_header.py | 33 +++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 docs_src/security/tutorial_api_key_header.py create mode 100644 tests/test_tutorial/test_security/test_tutorial_api_key_header.py diff --git a/docs/en/docs/tutorial/security/index.md b/docs/en/docs/tutorial/security/index.md index 6f460d627..e56b36ef4 100644 --- a/docs/en/docs/tutorial/security/index.md +++ b/docs/en/docs/tutorial/security/index.md @@ -104,3 +104,36 @@ FastAPI provides several tools for each of these security schemes in the `fastap In the next chapters you will see how to add security to your API using those tools provided by **FastAPI**. And you will also see how it gets automatically integrated into the interactive documentation system. + +## API Key in Header + +An API key is a simple secret string that a client sends with every request. +It is often used for: + +- machine-to-machine communication, +- internal services, +- simple “service access” authentication instead of full user accounts. + +In OpenAPI, this is represented with the `apiKey` security scheme, and it can be sent in a **query parameter**, a **header**, or a **cookie**. + +FastAPI provides tools for these in the `fastapi.security` module, including `APIKeyHeader` for header-based API keys. + +### Define an API key in a header + +In this example, the client must send an API key in the HTTP header `X-API-Key`. +We’ll require the exact value `"supersecret"` to access a protected route. + +```Python +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) + + diff --git a/docs/es/docs/tutorial/security/index.md b/docs/es/docs/tutorial/security/index.md index e4d75d8a4..c032eb13d 100644 --- a/docs/es/docs/tutorial/security/index.md +++ b/docs/es/docs/tutorial/security/index.md @@ -103,3 +103,36 @@ FastAPI proporciona varias herramientas para cada uno de estos esquemas de segur En los siguientes capítulos verás cómo agregar seguridad a tu API usando esas herramientas proporcionadas por **FastAPI**. Y también verás cómo se integra automáticamente en el sistema de documentación interactiva. + + +## API Key en el Header + +Una API key es una cadena secreta sencilla que un cliente envía con cada petición. +Suele utilizarse para: + +- comunicación entre servicios, +- servicios internos, +- autenticación simple por “acceso al servicio” en lugar de cuentas de usuario completas. + +En OpenAPI, esto se representa con el esquema de seguridad `apiKey`, que puede enviarse en un **parámetro de consulta**, un **header**, o una **cookie**. + +FastAPI incluye utilidades para esto en el módulo `fastapi.security`, incluyendo `APIKeyHeader` para API keys basadas en headers. + +### Definir la API key en un header + +En este ejemplo, el cliente debe enviar una API key en el header HTTP `X-API-Key`. +Requeriremos que el valor sea exactamente `"supersecret"` para acceder a una ruta protegida. + +```Python +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) + diff --git a/docs_src/security/tutorial_api_key_header.py b/docs_src/security/tutorial_api_key_header.py new file mode 100644 index 000000000..b06c6fe59 --- /dev/null +++ b/docs_src/security/tutorial_api_key_header.py @@ -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"} diff --git a/tests/test_tutorial/test_security/test_tutorial_api_key_header.py b/tests/test_tutorial/test_security/test_tutorial_api_key_header.py new file mode 100644 index 000000000..9bf65470b --- /dev/null +++ b/tests/test_tutorial/test_security/test_tutorial_api_key_header.py @@ -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"} From 0fc3ff387d98c2845352bbc40c885e6863fc5917 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 02:48:40 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8E=A8=20[pre-commit.ci]=20Auto=20for?= =?UTF-8?q?mat=20from=20pre-commit.com=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/tutorial/security/index.md | 6 ++---- docs/es/docs/tutorial/security/index.md | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/en/docs/tutorial/security/index.md b/docs/en/docs/tutorial/security/index.md index e56b36ef4..077d8d6d7 100644 --- a/docs/en/docs/tutorial/security/index.md +++ b/docs/en/docs/tutorial/security/index.md @@ -107,7 +107,7 @@ And you will also see how it gets automatically integrated into the interactive ## API Key in Header -An API key is a simple secret string that a client sends with every request. +An API key is a simple secret string that a client sends with every request. It is often used for: - machine-to-machine communication, @@ -120,7 +120,7 @@ FastAPI provides tools for these in the `fastapi.security` module, including `AP ### Define an API key in a header -In this example, the client must send an API key in the HTTP header `X-API-Key`. +In this example, the client must send an API key in the HTTP header `X-API-Key`. We’ll require the exact value `"supersecret"` to access a protected route. ```Python @@ -135,5 +135,3 @@ API_KEY = "supersecret" API_KEY_NAME = "X-API-Key" api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False) - - diff --git a/docs/es/docs/tutorial/security/index.md b/docs/es/docs/tutorial/security/index.md index c032eb13d..606767f4c 100644 --- a/docs/es/docs/tutorial/security/index.md +++ b/docs/es/docs/tutorial/security/index.md @@ -107,7 +107,7 @@ Y también verás cómo se integra automáticamente en el sistema de documentaci ## API Key en el Header -Una API key es una cadena secreta sencilla que un cliente envía con cada petición. +Una API key es una cadena secreta sencilla que un cliente envía con cada petición. Suele utilizarse para: - comunicación entre servicios, @@ -120,7 +120,7 @@ FastAPI incluye utilidades para esto en el módulo `fastapi.security`, incluyend ### Definir la API key en un header -En este ejemplo, el cliente debe enviar una API key en el header HTTP `X-API-Key`. +En este ejemplo, el cliente debe enviar una API key en el header HTTP `X-API-Key`. Requeriremos que el valor sea exactamente `"supersecret"` para acceder a una ruta protegida. ```Python @@ -135,4 +135,3 @@ API_KEY = "supersecret" API_KEY_NAME = "X-API-Key" api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False) -