ИНСТР-401-403HTTP 4xx · AuthOWASPревизия 2026-05-07

Ошибка 401 vs 403

HTTP 401 (не аутентифицирован) vs 403 (нет прав). Когда что использовать. WWW-Authenticate, redirect to login.

⏱ работает в браузере · без регистрации
Инструмент · ИНСТР-401-403|real-time
calcal.ru / oshibka-401-vs-403-otlichie
Загрузка инструмента…
401
Unauthorized
403
Forbidden
auth
vs authz
0
Запросов к серверу

Сравнение 401 vs 403

Autentication (аутентификация) и Authorization (авторизация) — два разных понятия, которые часто путают. 401 vs 403 — это HTTP-выражение этой разницы. Authentication = «кто ты?». Authorization = «что тебе разрешено?». Сначала всегда первое, потом второе.

Аспект401 Unauthorized403 Forbidden
СемантикаНе аутентифицированАутентифицирован, нет прав
Кто я?Сервер не знаетСервер знает
Можно повторить?Да, с учётными даннымиНет, ничего не изменит
HeadersWWW-AuthenticateНе требуется
Frontend действиеRedirect на /loginПоказать «нет прав»
Когда использоватьНет cookie / токена истёкНе admin / заблокирован

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

Используйте 401 когда

  • HTTP-запрос пришёл БЕЗ cookie / authorization header.
  • Cookie / token истёк.
  • JWT signature не валидна.
  • Basic Auth не предоставлен.
  • Неверный пароль при логине.
  • API endpoint требует аутентификации, клиент анонимен.

Используйте 403 когда

  • User вошёл, но не admin (пытается /admin).
  • User заблокирован (banned).
  • Premium feature, но user на free плане.
  • IP в чёрном списке.
  • Geo-blocking (контент не для этой страны).
  • Read-only доступ, но запрос на изменение.
  • CSRF token mismatch.
  • Maintenance mode для всех кроме админов.
The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials. The 403 (Forbidden) status code indicates that the server understood the request but refuses to fulfill it.RFC 9110 — HTTP Semantics, IETF, 2022

Best practices

Express.js пример

// Middleware для проверки аутентификации (401)
function requireAuth(req, res, next) {
  const token = req.cookies?.session || req.headers.authorization?.split(' ')[1];

  if (!token) {
    return res.status(401)
      .header('WWW-Authenticate', 'Bearer')
      .json({ error: 'Authentication required' });
  }

  try {
    req.user = jwt.verify(token, process.env.JWT_SECRET);
    next();
  } catch (e) {
    return res.status(401)
      .header('WWW-Authenticate', 'Bearer error="invalid_token"')
      .json({ error: 'Invalid or expired token' });
  }
}

// Middleware для проверки прав (403)
function requireRole(role) {
  return (req, res, next) => {
    if (!req.user.roles?.includes(role)) {
      return res.status(403).json({
        error: 'Insufficient permissions',
        required_role: role,
      });
    }
    next();
  };
}

// Использование
app.get('/api/profile', requireAuth, ...);  // Возврат 401 если не вошёл
app.get('/api/admin', requireAuth, requireRole('admin'), ...);  // Возврат 403 если не admin

Frontend (React) — обработка 401/403

// axios interceptor
axios.interceptors.response.use(
  (response) => response,
  async (error) => {
    if (error.response?.status === 401) {
      // Попытаться обновить токен
      const success = await tryRefreshToken();
      if (success) {
        // Повторить оригинальный запрос
        return axios.request(error.config);
      }
      // Иначе — на login
      window.location.href = `/login?return_to=${
        encodeURIComponent(window.location.pathname)
      }`;
    } else if (error.response?.status === 403) {
      // Показать toast
      toast.error('У вас нет прав для этой операции');
      // ИЛИ redirect на специальную страницу
      // navigate('/access-denied');
    }
    return Promise.reject(error);
  }
);

Логирование

  • 401 — обычное явление, не критично логировать каждое. Но: rate-limit на 401 от одного IP — защита от brute-force.
  • 403 — ВАЖНО логировать каждое. Если пользователь массово получает 403 — это попытка эскалации привилегий или баг в правах.
  • Алерт при массовых 403 — >50 за час от одного user — возможна атака.

Безопасность

  • Не различайте «неверный логин» и «неверный пароль». Иначе атакующий может перебирать логины (account enumeration). Стандарт: «Неверный логин или пароль» для обоих случаев.
  • Rate limit на login. 5 попыток в 5 минут — защита от brute-force. После — captcha или временная блокировка.
  • Скрывайте sensitive ресурсы за 404. Если у пользователя нет прав на /admin/users/42 — возвращайте 404, не 403. Иначе атакующий узнает о существовании юзера 42.
  • HTTPS обязательно. Без него токены/cookie перехватываются в открытом виде.
  • HttpOnly + Secure + SameSite=Strict для cookie. Защита от XSS и CSRF.
ИСТОЧНИКИ
  1. RFC 9110 — HTTP Semantics. IETF. datatracker.ietf.org/doc/html/rfc9110. 2022.
  2. OWASP — Authentication Cheat Sheet. OWASP. cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html. 2024.
  3. MDN — 401 Unauthorized. Mozilla. developer.mozilla.org/en-US/docs/Web/HTTP/Status/401. 2024.
ЧАСТЫЕ ВОПРОСЫ

Часто задаваемые вопросы

401 Unauthorized — клиент НЕ АУТЕНТИФИЦИРОВАН (не вошёл в систему). Сервер не знает, кто это. 403 Forbidden — клиент аутентифицирован, но НЕ ИМЕЕТ ПРАВ на этот ресурс. Сервер знает кто это, но запрещает доступ. Парадокс: 401 называется «Unauthorized» (не авторизован), но семантически означает «не аутентифицирован». Историческая путаница в HTTP-стандарте.
Когда пользователь не вошёл в систему: (1) HTTP запрос без cookie/токена, страница требует логина. (2) Токен истёк — нужно повторно войти. (3) Невалидный пароль при логине. (4) JWT с broken signature. На 401 клиент должен ОТПРАВИТЬ учётные данные. Сервер вернёт WWW-Authenticate header указывая способ (Basic, Bearer, Digest).
Когда пользователь вошёл, но не имеет прав: (1) Обычный пользователь пытается открыть admin panel. (2) Аккаунт заблокирован. (3) Достигнут лимит подписки (premium feature на free plan). (4) IP в чёрном списке. (5) Контент недоступен в стране (geo-blocking). На 403 клиент НЕ должен повторять с другими учётными данными — это ничего не изменит. Нужно сменить аккаунт или связаться с админом.
HTTP-заголовок, отправляемый с 401 ответом. Указывает клиенту КАК аутентифицироваться. Примеры: <code>WWW-Authenticate: Basic realm="Admin"</code> — Basic Auth (login/password). <code>WWW-Authenticate: Bearer</code> — JWT/OAuth токен. <code>WWW-Authenticate: Digest realm="..."</code> — Digest (старый, редко используется). Без этого заголовка 401 — нарушение HTTP-стандарта. Браузер на Basic auth показывает диалог входа.
403 — ресурс СУЩЕСТВУЕТ, но запрещён. 404 — ресурс не существует. Иногда сайты возвращают 404 ВМЕСТО 403 чтобы скрыть факт существования секретных URL. Это называется security through obscurity. Пример: GitHub возвращает 404 для приватных репо неавторизованным — атакующий не знает, есть ли репо вообще. Для public API лучше использовать чёткие коды (403 = нет прав), для критичной безопасности — 404.
Frontend: redirect на /login + сохранить ссылку для возврата (?return_to=/secret-page). После логина — обратно. Если уже на /login и получили 401 — показать «неверный пароль». Mobile: если у access token exp — попытаться обновить через refresh token. Если refresh тоже 401 — logout и redirect на login. Никогда не показывайте «401 Unauthorized» голым — это пугает пользователей. Дружелюбное «Войдите в систему» лучше.
Показать дружелюбное сообщение: «У вас нет прав на эту операцию. Обратитесь к администратору или попробуйте другой аккаунт». Если premium feature — предложить upgrade. Если geo-blocking — VPN. НЕ редиректьте на login — это бесполезно (повторный вход не даст прав). Логируйте 403 на сервере — если их много от одного user_id, возможно баг в правах или попытка эскалации привилегий.
OWASP рекомендует: (1) Возвращать 401 ТОЛЬКО для отсутствующей аутентификации. (2) Возвращать 403 при недостаточных правах после успешной аутентификации. (3) Включать WWW-Authenticate в 401 ответы. (4) Логировать все 403 (потенциальная попытка эскалации). (5) Использовать одинаковое сообщение для «неверный логин» и «неверный пароль» — защита от enumeration аккаунтов. (6) Rate limit на 401 — защита от brute-force.
Лиана Арифметова
АВТОРverifiedред. calcal.ru

Лиана Арифметова

Создатель и главный редактор

Миссия: демократизировать сложные расчёты. Превратить страх перед числами в ясность и контроль. Девиз: «Любая повторяющаяся задача заслуживает своего калькулятора».

Mathematical Engineering · МФТИ · редактирует каталог с 2012 года

Был ли этот калькулятор полезен?

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ

Инструмент справочный — не заменяет эксперта

Только для информационных целей. Все расчёты, результаты и данные, предоставляемые инструментом, носят исключительно ознакомительный и справочный характер. Они не являются профессиональной консультацией — медицинской, юридической, финансовой, инженерной или иной.

Точность результатов. Калькулятор основан на общепринятых формулах и методиках, однако фактические результаты могут отличаться в зависимости от индивидуальных условий, исходных данных и применяемых стандартов. Мы не гарантируем полноту, точность или актуальность приведённых расчётов.

Профессиональные решения — медицинские, финансовые, инженерные — должны приниматься только после консультации с квалифицированным специалистом. Не используйте автоматический расчёт как единственное основание для важных решений.

Ограничение ответственности. Авторы и разработчики сервиса не несут ответственности за прямой или косвенный ущерб, возникший из-за использования данных расчётов. Пользователь принимает на себя всю ответственность за интерпретацию результатов.