Как cookie переходят с сайта на сервис авторизации?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Передача cookies при редиректе на сервис авторизации
Это отличный вопрос, который касается безопасности и механики работы HTTP-запросов. Ответ более сложный, чем может показаться на первый взгляд.
Краткий ответ
Cookies НЕ переходят автоматически при редиректе на другой домен. Это сделано намеренно в целях безопасности (Same-Origin Policy). Однако существуют механизмы для передачи информации о сессии.
Same-Origin Policy и cookies
Same-Origin Policy — это фундаментальный механизм безопасности браузера:
// Сценарий 1: Редирект на другой домен
window.location = 'https://auth.service.com/login';
// Cookies домена site.com НЕ будут отправлены auth.service.com
// Почему это хорошо:
// - Предотвращает кража session cookies
// - Защищает от CSRF атак
// - Изолирует сессии между сервисами
Куки отправляются только на тот домен, который их установил:
// На site.com
res.setHeader('Set-Cookie', 'sessionId=abc123; Domain=.site.com');
// Браузер отправит эту куку только на site.com и субдомены
// На auth.service.com
res.setHeader('Set-Cookie', 'authToken=xyz789; Domain=.auth.service.com');
// Это другая кука для другого домена
Сценарии авторизации
Сценарий 1: Редирект с параметром
Мост простой способ — передать информацию в URL:
// На site.com
const state = generateRandomState();
const codeChallenge = generateCodeChallenge();
const authUrl = new URL('https://auth.service.com/login');
authUrl.searchParams.set('client_id', 'my-app');
authUrl.searchParams.set('redirect_uri', 'https://site.com/callback');
authUrl.searchParams.set('state', state); // Защита от CSRF
authUrl.searchParams.set('code_challenge', codeChallenge);
window.location = authUrl.toString();
Сервис авторизации получит все необходимые параметры и не нужны cookies.
Сценарий 2: OAuth 2.0 Code Flow (стандартный подход)
Это наиболее безопасный и рекомендуемый способ:
// Шаг 1: Frontend редирект
const authUrl = `https://auth.service.com/authorize?
client_id=${CLIENT_ID}&
redirect_uri=${encodeURIComponent('https://site.com/callback')}&
response_type=code&
state=${state}&
scope=openid profile email`;
window.location = authUrl;
// Шаг 2: Сервис авторизации (auth.service.com)
// Пользователь логинится там, получает authorization code
// Шаг 3: Backend-to-backend обмен
// site.com/backend отправляет POST запрос на auth.service.com/token
// Включает code и client_secret (важно: secret НЕ отправляем с фронта!)
const response = await fetch('https://auth.service.com/token', {
method: 'POST',
body: JSON.stringify({
grant_type: 'authorization_code',
code: code, // Получили из callback
client_id: CLIENT_ID,
client_secret: SECRET, // Только на backend!
redirect_uri: 'https://site.com/callback',
}),
});
const { access_token, id_token, refresh_token } = await response.json();
// Шаг 4: Backend устанавливает secure cookie в браузер
res.setHeader('Set-Cookie',
`sessionId=${sessionId};
Domain=site.com;
Path=/;
HttpOnly;
Secure;
SameSite=Strict;
Max-Age=3600`);
Когда cookies отправляются автоматически
Куки отправляются, если выполняются условия:
// 1. Same-origin запрос
fetch('/api/user'); // Отправит cookies site.com
// 2. Cross-origin с credentials
fetch('https://auth.service.com/api/user', {
credentials: 'include', // Отправит cookies auth.service.com
});
// Но это требует CORS заголовка на сервере:
// Access-Control-Allow-Credentials: true
// Access-Control-Allow-Origin: https://site.com (конкретный домен!)
// 3. Cookies с SameSite=None и Secure
res.setHeader('Set-Cookie',
`token=abc; SameSite=None; Secure; Domain=.auth.service.com`);
// Позволяет отправлять куки в cross-site запросах
// Требует HTTPS и явного CORS
Практический пример: Auth service и Main site
// auth.service.com
// GET /login
res.setHeader('Set-Cookie',
`authToken=${token};
Domain=.auth.service.com;
Path=/;
HttpOnly;
Secure;
SameSite=Strict`);
// site.com отправляет сюда запросы
fetch('https://auth.service.com/api/verify', {
credentials: 'include', // Включит cookies auth.service.com
});
// Сервер на auth.service.com получит authToken куку
Best Practices
1. Никогда не передавайте sensitive данные в URL:
// Плохо - tokens в параметрах
window.location = `https://site.com/callback?access_token=${token}`;
// Хорошо - используйте authorization code
window.location = `https://site.com/callback?code=${code}&state=${state}`;
2. Используйте HttpOnly cookies:
// Защищает от XSS — JavaScript не может получить куку
res.setHeader('Set-Cookie', 'token=abc; HttpOnly; Secure; SameSite=Strict');
3. Validate state параметр:
// Защита от CSRF
const state = crypto.randomUUID();
sessionStorage.setItem('auth_state', state);
// На callback
const receivedState = new URLSearchParams(location.search).get('state');
if (receivedState !== sessionStorage.getItem('auth_state')) {
throw new Error('CSRF attempt detected');
}
Итог
Cookies не переходят между доменами автоматически, и это правильно. Вместо этого используются:
- Authorization codes (OAuth 2.0)
- State параметры (защита от CSRF)
- Backend-to-backend обмены для sensitive данных
- Secure HttpOnly cookies для хранения session на нужном домене
Это обеспечивает безопасность и правильное разделение сессий между сервисами.