Ошибка 401 Unauthorized означает, что запрос не прошёл аутентификацию: сервер не понял, кто вы, потому что вы не предоставили валидные учётные данные. Главная причина — отсутствующий, неверный или истёкший сертификат токен либо сессия. По стандарту сервер обязан вернуть заголовок WWW-Authenticate, подсказывающий, какая схема аутентификации нужна.
В этой статье разберём формулировку стандарта, роль заголовков WWW-Authenticate и Authorization, ключевое отличие 401 от 403, основные схемы (Basic, Bearer, Digest), причины со стороны клиента и сервера и способы исправить ошибку.
Что значит ошибка 401 Unauthorized
Код 401 Unauthorized относится к клиентским ошибкам 4xx. Согласно RFC 9110, §15.5.2, он означает, что «запрос не был применён, потому что ему не хватает валидных учётных данных аутентификации для целевого ресурса». Название вводит в заблуждение: несмотря на слово «Unauthorized» (неавторизован), речь идёт именно об аутентификации — то есть о том, что сервер не смог установить вашу личность.
Стандарт требует: ответ 401 обязан содержать заголовок WWW-Authenticate хотя бы с одним challenge, применимым к ресурсу. Этот заголовок сообщает клиенту, какую схему аутентификации использовать.
Как выглядит ответ 401
HTTP/1.1 401 UnauthorizedWWW-Authenticate: Bearer realm="api", error="invalid_token"Content-Type: application/json{ "error": "token_expired" }Роль заголовков WWW-Authenticate и Authorization
Аутентификация в HTTP — это диалог двух заголовков. Сначала сервер отвечает 401 с WWW-Authenticate (challenge — «представься так-то»). Затем клиент повторяет запрос с заголовком Authorization, где передаёт учётные данные в нужной схеме.
GET /api/profile HTTP/1.1Host: example.comAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Если Authorization отсутствует, неверен или токен в нём истёк, сервер снова возвращает 401.
401 vs 403: в чём разница
Эти два кода путают чаще всего. Кратко: 401 — «я не знаю, кто ты» (проблема аутентификации), 403 — «я знаю, кто ты, но тебе сюда нельзя» (проблема авторизации). Таблица ниже раскрывает различия.
| Аспект | 401 Unauthorized | 403 Forbidden |
|---|---|---|
| Суть | Не пройдена аутентификация | Не пройдена авторизация |
| Кто вы для сервера | Личность не установлена | Личность известна |
| Когда возникает | Нет/неверные/истёкшие креды | Прав недостаточно для ресурса |
| Обязательный заголовок | WWW-Authenticate (обязателен) | Не требуется |
| Поможет ли вход | Да, повторная аутентификация может помочь | Нет, повторный вход не изменит прав |
| Что делать | Войти заново, обновить токен | Запросить доступ у администратора |
Схемы аутентификации: Basic, Bearer, Digest
Заголовок WWW-Authenticate указывает схему. Три самые распространённые:
- Basic — логин и пароль, закодированные в Base64 (только по SSL/TLS проверку!).
Authorization: Basic dXNlcjpwYXNz - Bearer — токен доступа (обычно JWT или OAuth 2.0).
Authorization: Bearer <token> - Digest — хеш-ответ на challenge сервера, не передаёт пароль в открытом виде.
Пример Basic-аутентификации
curl -v https://example.com/private -H "Authorization: Basic dXNlcjpwYXNzd29yZA=="Строка dXNlcjpwYXNzd29yZA== — это всего лишь user:password, закодированные в Base64. Декодировать её тривиально, поэтому Basic без HTTPS фактически передаёт пароль открытым текстом. Схема Bearer лишена этого недостатка: токен можно сделать короткоживущим и отозвать в любой момент, не меняя пароль пользователя. Именно поэтому современные API документацию почти всегда используют Bearer, а Basic оставляют для внутренних сервисов и служебных эндпоинтов за HTTPS.
Причины ошибки 401 и как исправить
Причины делятся на клиентские и серверные.
- Истёкший токен или сессия — самая частая причина у API. Решение: обновить access-токен через refresh-токен или войти заново.
- Неверные учётные данные — опечатка в логине/пароле, неправильный API-ключ. Решение: перепроверить креды.
- Отсутствует заголовок Authorization — клиент вовсе не отправил учётные данные. Решение: добавить заголовок.
- Неверная схема — сервер ждёт Bearer, а клиент шлёт Basic. Решение: сверить с WWW-Authenticate.
- Серверная настройка — например, включён
auth_basicв nginx или требуется API-ключ.
Серверная настройка Basic Auth в nginx
location /admin/ { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd;}При такой конфигурации любой запрос к /admin/ без корректного заголовка Authorization получит 401 и challenge Basic.
Токены и сессии: почему 401 возникает у залогиненных пользователей
Парадокс «я вошёл, но получаю 401» объясняется жизненным циклом токенов. В современных API access-токен намеренно живёт недолго — от нескольких минут до часа. Это ограничивает ущерб, если токен утечёт. Когда срок истекает, сервер отвечает 401, и клиент должен обменять долгоживущий refresh-токен на новый access-токен.
POST /oauth/token HTTP/1.1Host: example.comContent-Type: application/x-www-form-urlencodedgrant_type=refresh_token&refresh_token=def502...&client_id=appГрамотный клиент перехватывает первый 401, автоматически обновляет токен и повторяет исходный запрос — пользователь даже не замечает паузы. Если этой логики нет, пользователь видит внезапный выход из системы. Поэтому обработка 401 — обязательная часть любого API-клиента.
Типичные серверные причины 401 в API
- Ротация ключей — старый API-ключ отозван, приложение всё ещё шлёт его.
- Рассинхрон часов — JWT с полем
expсчитается истёкшим из-за неверного времени на сервере. - Неверный
realmили audience — токен выдан для другого сервиса. - Отозванная сессия — администратор принудительно завершил сессию пользователя.
Как проверить заголовки и аутентификацию
Чтобы увидеть код ответа и заголовок WWW-Authenticate, воспользуйтесь бесплатной проверкой HTTP-заголовков и кода ответа на enterno.io — она сразу покажет статус и все анализ заголовков ответа. А чтобы оценить общую защищённость эндпоинта и корректность схем аутентификации, пригодится сканер безопасности. Проверка заголовков ответа особенно полезна, когда нужно понять, какую именно схему (Basic, Bearer, Digest) ждёт сервер, — эта информация всегда содержится в challenge заголовка WWW-Authenticate.
Как правильно проектировать 401 в своём API
Если вы разрабатываете API, корректная реализация 401 повышает и безопасность, и удобство для клиентов. Придерживайтесь нескольких правил.
- Всегда возвращайте WWW-Authenticate с указанием схемы и, по возможности, поля
error(например,invalid_token,expired_token) — так клиент поймёт, обновить токен или запросить логин заново. - Не раскрывайте лишнего. Тело ответа не должно подсказывать, существует ли пользователь: одинаковый ответ на «неверный пароль» и «нет такого логина» защищает от перебора учётных записей.
- Разделяйте 401 и 403. Возвращайте 401 только при проблеме аутентификации, а 403 — когда личность установлена, но прав не хватает. Смешение кодов путает клиентов и усложняет отладку.
- Ставьте короткий срок жизни access-токенам и поддерживайте механизм refresh-токенов, чтобы истечение не выбрасывало пользователя из сессии внезапно.
Соблюдение этих принципов делает поведение вашего API предсказуемым: клиенты смогут автоматически обрабатывать 401, не гадая, что именно пошло не так.
Связанные материалы
Разобраться в кодах ответа помогут справочник HTTP-кодов и разбор ошибки 403 Forbidden — их часто путают с 401. Полезно также понимать работу HTTP-заголовков, ведь именно они несут учётные данные.
Частые вопросы
Чем 401 отличается от 403?
401 Unauthorized означает провал аутентификации: сервер не установил вашу личность из-за отсутствующих, неверных или истёкших учётных данных. 403 Forbidden означает провал авторизации: сервер знает, кто вы, но у вас недостаточно прав. При 401 помогает повторный вход, при 403 — только расширение прав администратором.
Почему я получаю 401, хотя точно вошёл в систему?
Скорее всего, истёк ваш access-токен или серверная сессия. Токены доступа живут недолго (минуты), и после истечения сервер отвечает 401. Обновите токен через refresh-токен или войдите заново. Также проверьте, что заголовок Authorization действительно отправляется и содержит актуальное значение.
Обязателен ли заголовок WWW-Authenticate при ответе 401?
Да. По RFC 9110 сервер, возвращающий 401, обязан включить заголовок WWW-Authenticate минимум с одним challenge, применимым к ресурсу. Он сообщает клиенту, какую схему аутентификации использовать — Basic, Bearer, Digest и т. д. Отсутствие этого заголовка при 401 — нарушение стандарта.
Как исправить 401 при обращении к API?
Проверьте по порядку: отправляется ли заголовок Authorization, верна ли схема (Bearer против Basic), не истёк ли токен и корректен ли API-ключ. Прогоните запрос через curl -v, чтобы увидеть отправленные заголовки и ответ сервера, включая WWW-Authenticate с описанием ошибки.
Безопасна ли Basic-аутентификация?
Basic передаёт логин и пароль всего лишь закодированными в Base64 — это не шифрование, а обратимое кодирование. Использовать её допустимо только поверх HTTPS, где весь трафик зашифрован TLS. Без HTTPS учётные данные фактически передаются в открытом виде. Для API предпочтительнее схема Bearer с короткоживущими токенами.