Компьютерные сети
Authentication Flows
Authentication - самый критичный компонент безопасности. Ошибка здесь = утечка данных всех пользователей. Понимание как токены передаются по сети, где хранятся, как защищены - обязательное знание для любого backend разработчика.
- **Slack/Dropbox breach**: украденные OAuth токены дали доступ к аккаунтам - важность token revocation
- **GitHub fine-grained tokens**: эволюция от единого токена к scoped access для минимизации blast radius
- **Auth0/Okta**: managed auth сервисы, реализующие все best practices из коробки
Предварительные знания
Session-Based Auth
**Session-based auth** - классический подход: сервер создаёт session при логине, хранит state в памяти/Redis, клиент получает session ID в cookie. Каждый запрос проверяется против session store.
**Session store** (Redis/Memcached) - single point of failure. При масштабировании: sticky sessions или централизованный store. Logout мгновенный - удалить session из store.
Преимущества: сервер контролирует sessions (можно invalidate любую), простая имплементация. Недостатки: stateful (нужен shared store), latency на каждый запрос (Redis lookup).
Почему session ID должен храниться в HttpOnly cookie?
JWT (JSON Web Token)
**JWT** - stateless токен, содержащий claims (userId, role, expiry) и подпись. Сервер не хранит state - валидирует подпись при каждом запросе. Токен самодостаточен.
**JWT недостаток**: нельзя revoke до expiry. Решения: короткий expiry (15 min) + refresh token, или blacklist (но это снова stateful). Trade-off: stateless vs revocation.
Алгоритмы подписи: **HS256** (symmetric, shared secret), **RS256** (asymmetric, public/private key). RS256 позволяет проверять токены без знания secret - подходит для микросервисов.
Как сервер валидирует JWT без обращения к базе данных?
OAuth 2.0
**OAuth 2.0** - протокол авторизации для третьих сторон. Не путать с authentication! OAuth позволяет приложению получить доступ к ресурсам пользователя (Google Drive, GitHub repos) без передачи пароля.
**OIDC (OpenID Connect)** - надстройка над OAuth для authentication. Добавляет ID Token (JWT с user info), стандартизирует claims (sub, email, name). 'Login with Google' использует OIDC.
**PKCE** (Proof Key for Code Exchange) - защита для mobile/SPA без client_secret. Клиент генерирует code_verifier, отправляет его hash (code_challenge). При обмене code подтверждает владение verifier.
Почему authorization code обменивается на токены server-to-server?
Token Storage
Где хранить токены в браузере? **localStorage** удобно, но уязвимо к XSS. **HttpOnly cookie** защищена от XSS, но уязвима к CSRF. Правильный выбор зависит от threat model.
**BFF Pattern** для SPA: Backend For Frontend хранит токены в session, SPA общается только с BFF через cookies. API calls проксируются через BFF. Токены никогда не в браузере.
Memory-only storage (переменная в JS) - токен исчезает при refresh страницы. Подходит для высокочувствительных приложений, но требует silent refresh через iframe при каждой загрузке.
Почему localStorage для JWT считается небезопасным?
Refresh Tokens
**Refresh token** решает проблему: access token должен быть коротким (безопасность), но частый re-login плохой UX. Refresh token - долгоживущий токен для получения новых access tokens.
**Refresh token хранится в БД** (не stateless как JWT). Это позволяет revoke: удалить из БД = пользователь должен re-login при следующем refresh.
Безопасность: refresh token в HttpOnly cookie (не localStorage), rotation при каждом использовании, привязка к device fingerprint, ограничение concurrent sessions.
JWT безопаснее session cookies потому что токен подписан
JWT и sessions решают разные trade-offs. Sessions: instant revocation, но stateful. JWT: stateless, но нельзя revoke до expiry. Оба безопасны при правильной реализации
Session ID тоже невозможно подделать (случайный, длинный). JWT просто хранит claims в самом токене вместо сервера. Для разных приложений разные требования - нет универсально 'безопасного' решения.
Зачем нужен refresh token rotation?
Итоги
- **Sessions**: stateful, instant revoke, требует shared store (Redis)
- **JWT**: stateless, self-contained claims, нельзя revoke до expiry
- **OAuth 2.0**: авторизация третьих сторон, Authorization Code flow для безопасности
- **Token storage**: HttpOnly cookie + SameSite - защита от XSS и CSRF
- **Refresh tokens**: короткий access + долгий refresh, rotation для reuse detection
Связанные темы
Authentication пересекается с многими networking концепциями:
- TLS/HTTPS — Защита токенов при передаче по сети
- Cookies — Основной механизм хранения session/tokens в браузере
- API Gateway — Централизованная auth валидация на gateway уровне
Вопросы для размышления
- Когда выбрать sessions вместо JWT? И наоборот?
- Как реализовать logout при использовании JWT?
- Как защитить refresh token от кражи при XSS атаке?