Короткий ответ
Токен передают в заголовке Authorization: Bearer <token>; передача в query-параметре рискованна, так как URL часто логируется серверами, прокси и попадает в историю браузера, в отличие от заголовков.
Как это работает подробнее
HTTP-заголовки, в отличие от URL, как правило не попадают в access-логи веб-серверов и кэши промежуточных прокси по умолчанию (хотя сами заголовки тоже могут логироваться, если это явно настроено); сервер при каждом запросе читает заголовок Authorization и проверяет/декодирует токен (например, JWT) перед обработкой бизнес-логики.
Пример кода
example.py
from fastapi import FastAPI, Depends, HTTPException, Header
app = FastAPI()
def verify_token(authorization: str = Header(default=None)):
if not authorization or not authorization.startswith("Bearer "):
raise HTTPException(status_code=401, detail="Missing or invalid token")
token = authorization.removeprefix("Bearer ")
if not is_token_valid(token):
raise HTTPException(status_code=401, detail="Token expired or invalid")
return token
@app.get("/profile")
def get_profile(token: str = Depends(verify_token)):
return {"ok": True}Что использовать на практике
- Рекомендация. в Python такие проверки обычно реализуют через middleware или dependency (в FastAPI —
Depends), чтобы не дублировать код проверки токена в каждом эндпоинте. Токен стоит передавать только по HTTPS, иначе заголовок можно перехватить в открытом виде.
Подводные камни
- Риски. передавать токен в query-параметре "для простоты тестирования" и забывать убрать это в production-коде; хранить токен в логах при логировании полного запроса целиком, включая заголовки; не проверять срок действия (
exp) токена на сервере.