mirror of https://github.com/tiangolo/fastapi.git
Merge 0fc3ff387d into 272204c0c7
This commit is contained in:
commit
8fd7fc814e
|
|
@ -104,3 +104,34 @@ 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)
|
||||
|
|
|
|||
|
|
@ -103,3 +103,35 @@ 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)
|
||||
|
|
|
|||
|
|
@ -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