Короткий ответ
1xx — информационные, 2xx — успех, 3xx — перенаправление, 4xx — ошибка клиента, 5xx — ошибка сервера. 401 означает, что клиент не прошёл аутентификацию (не предоставил или предоставил неверные учётные данные), 403 — что клиент аутентифицирован, но у него нет прав на действие.
Как это работает подробнее
статус-код — часть HTTP-ответа, которая говорит клиенту, как интерпретировать результат без парсинга тела. 401 Unauthorized по спецификации обязан сопровождаться заголовком WWW-Authenticate, указывающим, как авторизоваться.
Пример кода
example.py
from fastapi import HTTPException
def get_order(order_id: int, current_user):
order = find_order(order_id)
if not order:
raise HTTPException(status_code=404, detail="Order not found")
if current_user is None:
raise HTTPException(status_code=401, detail="Authentication required")
if order.owner_id != current_user.id and not current_user.is_admin:
raise HTTPException(status_code=403, detail="Access denied")
return orderЧто использовать на практике
- Рекомендация. 401 возвращают, когда токен отсутствует, просрочен или некорректен; 403 — когда токен валиден, но роли/права не позволяют выполнить операцию (например, обычный пользователь пытается удалить чужой ресурс). Разделение важно для клиентов: при 401 стоит предложить повторный логин, при 403 — показать сообщение об отсутствии прав, а не предлагать перелогиниться.
Подводные камни
- Риски. возвращать 401 вместо 403 (или наоборот), что приводит к бесконечным попыткам логина в UI; использовать 500 для ошибок валидации пользовательских данных (должно быть 400/422); возвращать 200 с телом {"error": "..."}" вместо честного кода ошибки, что ломает автоматическую обработку ошибок на клиенте.