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

Какого типа авторизацию использовал?

1.0 Junior🔥 221 комментариев
#Браузер и сетевые технологии

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

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

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

Какого типа авторизацию использовал?

В своей практике я работал с несколькими типами авторизации и механизмами аутентификации. Дам обзор каждого подхода, когда его использовать и какие проблемы при этом возникают.

1. Session-Based Authentication (сессионная авторизация)

Это традиционный подход, когда сервер хранит информацию о сессии.

Как работает:

  • Пользователь отправляет логин/пароль
  • Сервер создаёт сессию и сохраняет в памяти (или БД)
  • Возвращает Session ID в cookie
  • Браузер автоматически отправляет cookie со всеми запросами
// Frontend — обычно ничего специального не требуется
fetch('/api/login', {
  method: 'POST',
  credentials: 'include', // отправить cookies
  body: JSON.stringify({ email, password })
});

// Все последующие запросы включают cookie автоматически
fetch('/api/profile', {
  credentials: 'include'
});

Backend (Express пример):

app.use(session({
  secret: 'my-secret',
  resave: false,
  saveUninitialized: true,
  cookie: { httpOnly: true, secure: true } // httpOnly защищает от XSS
}));

app.post('/login', (req, res) => {
  const user = findUser(req.body.email);
  if (user && validatePassword(user, req.body.password)) {
    req.session.userId = user.id; // сохраняем в сессии
    res.json({ success: true });
  } else {
    res.status(401).json({ error: 'Invalid credentials' });
  }
});

Когда использовать:

  • Традиционные веб-приложения
  • Монолитные приложения
  • Когда не нужна масштабируемость

Проблемы:

  • Сложно масштабировать (нужна общая память между серверами)
  • CSRF уязвимость (требует CSRF token)
  • Не подходит для мобильных приложений

2. Token-Based Authentication (JWT)

Модерный подход, когда сервер выдаёт токен, а клиент его отправляет в каждом запросе.

Как работает:

  • Пользователь отправляет логин/пароль
  • Сервер создаёт JWT токен (содержит данные о пользователе)
  • Клиент сохраняет токен (в localStorage или в памяти)
  • Клиент отправляет токен в Authorization header
// Frontend — JWT хранится в localStorage
const response = await fetch('/api/login', {
  method: 'POST',
  body: JSON.stringify({ email, password })
});

const data = await response.json();
localStorage.setItem('token', data.token);

// Отправляем токен в каждом запросе
fetch('/api/profile', {
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('token')}`
  }
});

Backend (Node.js + JWT):

const jwt = require('jsonwebtoken');

app.post('/login', (req, res) => {
  const user = findUser(req.body.email);
  if (user && validatePassword(user, req.body.password)) {
    const token = jwt.sign(
      { userId: user.id, email: user.email },
      'secret-key',
      { expiresIn: '1h' }
    );
    res.json({ token });
  } else {
    res.status(401).json({ error: 'Invalid credentials' });
  }
});

// Middleware для проверки токена
const verifyToken = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  try {
    const decoded = jwt.verify(token, 'secret-key');
    req.userId = decoded.userId;
    next();
  } catch (err) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

Когда использовать:

  • REST API
  • Микросервисная архитектура
  • Мобильные приложения
  • Single Page Applications (React, Vue, Angular)

Проблемы:

  • localStorage уязвим для XSS (токен может быть украден)
  • JWT большие и отправляются в каждом запросе
  • Невозможно отозвать токен (до истечения времени)
  • Нужно заботиться о refresh tokens

3. OAuth 2.0 (Авторизация через внешний сервис)

Использование сторонних сервисов (Google, GitHub, Facebook) для авторизации.

// Frontend — перенаправляем пользователя на Google
const loginWithGoogle = () => {
  const clientId = 'YOUR_CLIENT_ID';
  const redirectUri = 'http://localhost:3000/callback';
  const scope = 'openid email profile';
  
  window.location.href = 
    `https://accounts.google.com/o/oauth2/v2/auth?` +
    `client_id=${clientId}&` +
    `redirect_uri=${redirectUri}&` +
    `scope=${scope}&` +
    `response_type=code`;
};

// После редиректа назад, обмениваем код на токен
const handleCallback = async (code) => {
  const response = await fetch('/api/auth/google/callback', {
    method: 'POST',
    body: JSON.stringify({ code })
  });
  const data = await response.json();
  localStorage.setItem('token', data.token);
};

Backend:

app.post('/auth/google/callback', async (req, res) => {
  const { code } = req.body;
  
  // Обмен кода на токен Google
  const googleResponse = await fetch('https://oauth2.googleapis.com/token', {
    method: 'POST',
    body: JSON.stringify({
      code,
      client_id: process.env.GOOGLE_CLIENT_ID,
      client_secret: process.env.GOOGLE_CLIENT_SECRET,
      redirect_uri: process.env.REDIRECT_URI,
      grant_type: 'authorization_code'
    })
  });
  
  const googleToken = await googleResponse.json();
  const userInfo = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', {
    headers: { 'Authorization': `Bearer ${googleToken.access_token}` }
  }).then(r => r.json());
  
  // Создаём или получаем пользователя
  let user = findUserByEmail(userInfo.email);
  if (!user) {
    user = createUser({ email: userInfo.email, name: userInfo.name });
  }
  
  // Выдаём наш токен
  const token = jwt.sign({ userId: user.id }, 'secret');
  res.json({ token });
});

Когда использовать:

  • Социальная авторизация
  • Предоставление доступа к API
  • Enterprise интеграции

4. Cookies + HttpOnly (Защищённая авторизация)

Сочетание JWT в HttpOnly cookies + CSRF protection.

// Frontend
const login = async (email, password) => {
  const response = await fetch('/api/login', {
    method: 'POST',
    credentials: 'include', // отправить cookies
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password })
  });
  // Токен сохранён в cookies автоматически
  return response.ok;
};

// Все запросы автоматически включают cookie
fetch('/api/profile', { credentials: 'include' });

Backend:

app.post('/login', (req, res) => {
  const user = findUser(req.body.email);
  const token = jwt.sign({ userId: user.id }, 'secret');
  
  // HttpOnly cookie защищена от XSS
  res.cookie('token', token, {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 3600000
  });
  
  res.json({ success: true });
});

Когда использовать:

  • Нужна максимальная безопасность
  • Traditional веб-приложения
  • Когда клиент и сервер на одном домене

5. Двухфакторная авторизация (2FA)

Дополнительный уровень безопасности.

// Вторая форма после пароля
const enable2FA = async () => {
  const response = await fetch('/api/2fa/setup', { method: 'POST' });
  const { secret, qrCode } = await response.json();
  // Показываем QR код для сканирования
  return qrCode;
};

const verify2FA = async (code) => {
  const response = await fetch('/api/2fa/verify', {
    method: 'POST',
    body: JSON.stringify({ code })
  });
  return response.ok;
};

Сравнение подходов

КритерийSessionJWTOAuth2HttpOnly Cookie
БезопасностьСредняяСредняяВысокаяВысокая
МасштабируемостьНизкаяВысокаяN/AВысокая
Мобильные приложенияПлохоХорошоОтличноНельзя
СложностьНизкаяСредняяВысокаяСредняя
CSRF уязвимость✅ Требует защиты❌ ЗащищенаN/A✅ Требует защиты

Лучшие практики

  1. Никогда не храни пароли в plain text — используй bcrypt/argon2
  2. Отправляй данные по HTTPS — не по HTTP
  3. HttpOnly cookies для токенов — защита от XSS
  4. Short-lived токены + refresh tokens — security vs convenience
  5. Implement rate limiting — защита от brute force
  6. Rotate secrets regularly — обновляй ключи
  7. Log security events — логируй попытки доступа

Рекомендация для современных приложений

Для SPA + REST API:

Клиент → (логин/пароль) → Сервер
Сервер → (httpOnly token) → Браузер
Клиент ← (автоматически) ← Токен в cookie

Этот подход сочетает безопасность httpOnly cookies с удобством JWT токенов.

Какого типа авторизацию использовал? | PrepBro