401 Unauthorized
Применение
Получив ошибку 401 Unauthorized, клиент понимает, что перед предоставлением доступа к запрошенному ресурсу требуются действительные учётные данные для входа. Клиенту нужно сначала войти в систему либо передать учётные данные в составе HTTP-запроса. Учётные данные, уже отправленные вместе с запросом, также недействительны. Этот статус отличается от 403 Forbidden, который сообщает клиенту, что действие не разрешено независимо от учётных данных.
Примечание
Название «Unauthorized» исторически вводит в заблуждение. 401 означает, что клиент не прошёл аутентификацию: учётные данные отсутствуют или недействительны. Аутентифицированные пользователи, у которых нет прав на выполнение запрошенного действия, получают вместо этого 403 Forbidden. Такое наименование сохранилось со времён первоначальной спецификации HTTP/1.0.
Когда сервер отправляет ответ 401 Unauthorized, в него включается заголовок ответа WWW-Authenticate. Он сообщает клиенту о допустимых методах авторизации. IANA ведёт список стандартных схем аутентификации, различающихся по безопасности и распространённости. Распространённые схемы аутентификации:
Basic
Передаёт учётные данные в виде пар ID/пароль.
Bearer
Также известна как аутентификация по токену: опирается на токены безопасности, которые сервер генерирует и возвращает клиенту после успешного входа. Клиент отправляет эти токены в последующих запросах для доступа к защищённым ресурсам. При необходимости сервер включает подробности об ошибке: WWW-Authenticate: Bearer error=“invalid_token”, error_description=“Token expired”.
Digest
Протокол «запрос-ответ» (challenge-response), используемый для аутентификации запросов к ресурсам.
HOBA
Сокращение от HTTP Origin-Bound Authentication — схема, не требующая от сервера хранения паролей, благодаря чему она устойчива к фишинговым атакам.
Mutual
Также известна как двусторонняя аутентификация; схожа со схемами Basic и Digest, с тем отличием, что сервер гарантированно знает зашифрованный пароль клиента. Клиент и сервер аутентифицируют друг друга до продолжения взаимодействия.
AWS4-HMAC-SHA256
Алгоритм аутентификации, предоставляющий сведения об аутентификации для Amazon Web Services AWS S3 API Reference.
Сервер может указать несколько методов аутентификации — в нескольких строках или в одной строке через запятую. Когда у клиента есть необходимые учётные данные, он отправляет их в заголовке запроса Authorization.
Влияние на SEO
Поисковые системы, такие как Google, не индексируют URL, возвращающий статус 401 Unauthorized. Ранее проиндексированные URL, которые начинают возвращать этот код состояния, удаляются из результатов поиска. Страницы, возвращающие этот код, не расходуют краулинговый бюджет. Не используйте 401 для замедления Googlebot. Снизить частоту сканирования позволяет только 429.
Пример
Клиент запрашивает ресурс, и сервер отвечает 401 Unauthorized, показывая, что ресурс защищён. Сервер указывает на поддержку как Basic, так и Mutual авторизации. Клиент отвечает парой username:password по протоколу аутентификации Basic, указанной в заголовке Authorization. После этого сервер передаёт запрошенный ресурс.
Первоначальный запрос
GET /documents/tech-news HTTP/1.1
Host: example.com
Первоначальный ответ
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Documents"
WWW-Authenticate: Mutual
Следующий запрос, включающий Authorization
GET /documents/tech-news HTTP/1.1
Host: example.com
Authorization: Basic RXhhbXBsZTphaQ==
Итоговый ответ
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Length: 25000
<PDF document included in message body>
Как исправить
401 Unauthorized означает, что сервер требует действительные учётные данные, прежде чем предоставить доступ.
Проверьте заголовок WWW-Authenticate в ответе. Этот заголовок указывает ожидаемую схему аутентификации (Basic, Bearer, Digest и т. д.). Приведите запрос клиента в соответствие с требуемой схемой. Откройте DevTools браузера, выберите вкладку Network и найдите запись WWW-Authenticate в разделе Response Headers.
Проверьте учётные данные. Убедитесь в правильности имени пользователя и пароля, API-ключа или bearer-токена. Единственная опечатка или пробельный символ в значении заголовка Authorization приводит к отказу. Протестируйте учётные данные изолированно с помощью curl -H “Authorization: Bearer
Убедитесь, что срок действия токена не истёк. Bearer-токены и сессионные токены имеют ограниченное время жизни. Декодируйте JWT в локальном отладчике, чтобы проверить утверждение exp. Перевыпустите или обновите токен доступа через провайдера аутентификации.
Приведите формат заголовка Authorization в соответствие со схемой. Basic ожидает пару username:password в кодировке Base64. Bearer ожидает «сырую» строку токена. Неверный формат вызывает 401 даже при действительных учётных данных. Распространённая ошибка — пропуск префикса схемы (отправка одного лишь токена без Bearer ).
При необходимости перевыпустите учётные данные. Смените API-ключ или запросите новый токен у сервера авторизации. Отозванные или аннулированные учётные данные всегда приводят к этому статусу.
Очистите кэш браузера и cookie. Устаревшие сессионные cookie или закэшированные заголовки Authorization конфликтуют с обновлёнными учётными данными. Удалите сохранённые данные и пройдите аутентификацию заново.
Проверьте конфигурацию аутентификации на стороне сервера. Доступом управляют файлы .htpasswd в Apache, директивы auth_basic в nginx и правила AuthType в .htaccess. Убедитесь, что путь к файлу учётных данных, имя realm и запись пользователя существуют. В nginx:
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
В Apache:
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
Проверьте области действия OAuth и утверждения audience. Токен доступа с корректными учётными данными, но неверными областями действия либо с утверждением aud, не соответствующим серверу ресурсов, всё равно вызовет 401. Убедитесь, что токен выпущен для целевого API.
Примеры кода
.NET
HttpStatusCode.Unauthorized
Rust
http::StatusCode::UNAUTHORIZED
Rails
:unauthorized
Go
http.StatusUnauthorized
Symfony
Response::HTTP_UNAUTHORIZED
Python3.5+
http.HTTPStatus.UNAUTHORIZED
Java
java.net.HttpURLConnection.HTTP_UNAUTHORIZED
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_UNAUTHORIZED
Angular
@angular/common/http/HttpStatusCode.Unauthorized