Авторизация на сайте: cookies, токены, OAuth
Каким способом может выполняться авторизация пользователя на сайте?
Теория: аутентификация и авторизация
В веб-разработке важно различать два близких понятия. Аутентификация отвечает на вопрос «кто это?», а авторизация — «что этому разрешено делать?».
В учебных вопросах словом «авторизация» часто называют именно процесс входа, то есть проверку личности, и последующее поддержание состояния «пользователь вошёл». Поскольку HTTP-запросы сами по себе не содержат «памяти о прошлом», серверу требуется получать при каждом запросе некоторый идентификатор или доказательство того, что запрос выполняется от имени конкретного пользователя.
Отсюда возникает практическая задача: после успешного входа необходимо «привязать» дальнейшие запросы к пользователю, чтобы сервер мог:
- Узнать пользователя.
- Проверить срок действия входа.
- Проверить права (роль, доступ к конкретным ресурсам).
Сессионные cookie (сервер хранит сессию)
Cookie — это небольшой фрагмент данных, который сервер отправляет браузеру, а браузер затем автоматически отправляет обратно этому же сайту в последующих запросах.
Типичный сценарий:
- Пользователь отправляет логин/пароль на
/login. - Сервер проверяет данные и создаёт запись сессии на своей стороне (например, в памяти, Redis, базе данных).
- Сервер отправляет cookie с идентификатором сессии (например,
sid=...). - Браузер автоматически прикрепляет cookie к следующим запросам, а сервер по
sidнаходит сессию и понимает, кто выполняет запрос.
Пример (упрощённо): создание сессии и установка cookie
// Псевдокод: идея одинакова во многих языках/фреймворках
POST /login
-> проверить пароль
-> sessionId = random()
-> sessions[sessionId] = { userId: 123, createdAt: now(), expiresAt: now()+... }
-> ответ:
Set-Cookie: sid=sessionId; HttpOnly; Secure; SameSite=Lax
200 OK
GET /profile
(браузер автоматически отправляет Cookie: sid=sessionId)
-> сервер читает sid
-> находит sessions[sid]
-> если найдено и не истекло, отдаёт страницу/JSON
Зачем серверное хранилище сессий удобно:
- Можно быстро «отозвать» вход: достаточно удалить сессию на сервере.
- Можно хранить дополнительные признаки (например, время входа, устройство, CSRF-токен, флаги безопасности).
- Можно централизованно применять правила (ограничение по времени, принудительный выход).
HttpOnly, Secure, SameSite) и защита от XSS.Токены и заголовок Authorization: Bearer
Токенный подход означает, что клиент хранит токен и отправляет его с каждым запросом к защищённому API. Часто токен передаётся в заголовке авторизации: Authorization: Bearer ....
Это описано в спецификациях семейства OAuth 2.0 (например, RFC 6750 для Bearer Token Usage), где задаётся стандартный формат передачи токена, включая пример заголовка Authorization: Bearer <token>.
Пример HTTP-запроса с Bearer-токеном
GET /api/orders HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOi...
Пример серверной проверки (упрощённо)
function authMiddleware(req):
header = req.headers["authorization"]
if header is missing:
return 401
if not header startsWith "Bearer ":
return 401
token = header after "Bearer "
claims = verifyAndDecode(token) // подпись, срок действия, аудитория и т.п.
if claims invalid:
return 401
req.userId = claims.sub
return next()
Особенность Bearer-токена: «кто владеет токеном, тот и проходит проверку». Поэтому утечка токена обычно равна утечке доступа на время жизни токена, и требуется строго защищать каналы передачи (TLS) и место хранения.
OAuth 2.0 (федеративный вход)
OAuth 2.0 — это стандарт, описывающий делегирование доступа: клиентское приложение получает токен доступа к ресурсам от сервера авторизации. В сценарии «вход через провайдера» (например, через отдельный аккаунт-провайдер) OAuth 2.0 часто используется совместно со стандартами, которые добавляют «слой идентичности» (например, OpenID Connect).
Один из распространённых потоков — Authorization Code:
- Клиент перенаправляет браузер пользователя на endpoint авторизации.
- Пользователь аутентифицируется на стороне сервера авторизации и подтверждает согласие.
- Сервер авторизации перенаправляет браузер обратно на сайт клиента с параметром
code. - Сервер клиента (или доверенный backend) обменивает
codeнаaccess_token(и иногдаrefresh_token). - Далее запросы к API выполняются с предъявлением токена.
Схема (упрощённо) Authorization Code Flow
Пользователь -> Клиент (сайт) -> Сервер авторизации -> Клиент -> Ресурсный сервер
1) Клиент: redirect на /authorize
2) Сервер авторизации: вход + согласие
3) Redirect обратно: ?code=...
4) Клиент: POST /token (обмен code на access_token)
5) Клиент/приложение: запросы к API с access_token
Почему DNS, CSS/HTML и CDN-кэш — не авторизация
DNS: DNS решает задачу именования (как по доменному имени находить нужные сетевые параметры), но не содержит модели «конкретный пользователь вошёл в систему» и не обеспечивает проверку прав на уровне запросов к веб-приложению.
CSS/HTML: CSS описывает внешний вид (оформление), HTML — структуру документа. Эти технологии не предназначены для криптографической проверки личности и не дают серверу проверяемого доказательства, что запрос сделан именно конкретным пользователем.
CDN-кэш: CDN занимается доставкой и кэшированием. Кэш может хранить и повторно выдавать ответы, но это не является подтверждением личности. Наоборот, при неправильных настройках кэша возможно случайное распространение приватного контента, поэтому приватные страницы обычно помечаются так, чтобы кэширование происходило безопасно (или не происходило вовсе), а доступ контролировался cookie/токенами на сервере.
Таблица: чем отличаются подходы
| Подход | Что отправляется в каждом запросе | Где хранится «состояние входа» | Типичный плюс | Типичный риск/сложность |
|---|---|---|---|---|
| Сессионные cookie | Cookie: sid=... (автоматически браузером) | На сервере (сессия по sid) | Удобно для классических сайтов, легко отзывать сессию | Риски при XSS/угоне cookie, важны атрибуты безопасности |
| Bearer-токен | Authorization: Bearer ... | Часто «внутри» токена и/или в системе проверки | Удобно для API и разных клиентов | Утечка токена обычно даёт доступ, важны срок жизни и отзыв |
| OAuth 2.0 | После получения — предъявление access token | Сервер авторизации выдаёт токены, ресурсный сервер проверяет | Делегирование доступа, пароль не передаётся клиенту | Больше компонентов и настроек, важны redirect URI и безопасность потока |
Итого: авторизация (в смысле «вход и поддержание состояния входа») обычно реализуется через сессионные cookie или через токены (например, Authorization: Bearer ...), а для входа через внешнего провайдера применяется OAuth 2.0; DNS, CSS/HTML и CDN-кэш не предназначены для подтверждения личности пользователя.