Ответ
Middleware для аутентификации WebSocket-соединений проверяет токен или другие учетные данные при установке соединения, обеспечивая безопасность. Это критически важно для защиты данных и контроля доступа к функциональности, предоставляемой через WebSocket.
Пример реализации для FastAPI с WebSocket:
from fastapi import WebSocket, WebSocketDisconnect, APIRouter
from fastapi.security import OAuth2PasswordBearer
from typing import Optional
router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") # Пример, токен может быть получен иначе
# Ваша функция для проверки токена
def verify_token(token: str) -> bool:
# Здесь должна быть реальная логика проверки токена (например, JWT)
# Возвращает True, если токен валиден, иначе False
return token == "valid_token" # Заглушка для примера
async def websocket_auth_middleware(websocket: WebSocket) -> Optional[str]:
"""
Middleware для аутентификации WebSocket-соединения.
Ожидает токен в первом текстовом сообщении.
"""
try:
# Токен может передаваться в первом сообщении или как query-параметр URL
token = await websocket.receive_text()
if not verify_token(token):
# Закрываем соединение с кодом 1008 (Policy Violation) и причиной
await websocket.close(code=1008, reason="Invalid authentication token")
raise WebSocketDisconnect("Authentication failed")
return token
except WebSocketDisconnect:
# Соединение уже закрыто или ошибка при получении токена
raise
@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
# Применяем middleware для аутентификации
token = await websocket_auth_middleware(websocket)
# Дальнейшая логика работы с аутентифицированным сокетом
await websocket.send_text(f"Hello, authenticated user with token: {token}")
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message text was: {data}")
except WebSocketDisconnect:
print("WebSocket disconnected, authentication failed or client closed connection.")
except Exception as e:
print(f"An error occurred: {e}")
Ключевые аспекты:
- Передача токена: Токен обычно передается в первом сообщении после установки соединения, в заголовках (если поддерживается протоколом) или как query-параметр URL при подключении. Выбор метода зависит от клиента и сервера.
- Обработка ошибок: Важно корректно закрывать соединение при ошибках аутентификации, используя соответствующие коды состояния WebSocket (например,
1008для нарушения политики,4000-4999для пользовательских кодов). Это позволяет клиенту понять причину разрыва. - Масштабирование: Для распределенных систем и масштабирования аутентификации и обмена сообщениями часто используются брокеры сообщений, такие как Redis Pub/Sub, Kafka или RabbitMQ, которые могут интегрироваться с механизмом аутентификации.