← Назад к вопросам

Как cookie переходят с сайта на сервис авторизации?

2.3 Middle🔥 161 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Передача 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 на нужном домене

Это обеспечивает безопасность и правильное разделение сессий между сервисами.

Как cookie переходят с сайта на сервис авторизации? | PrepBro