Можно ли отправить 401 Несанкционированный И перенаправление (с местоположением)? - PullRequest
35 голосов
/ 08 января 2012

Я хотел бы отправить 401 Unauthorized И перенаправить клиента куда-нибудь. Однако:

если я сделаю это так:

header('HTTP/1.1 401 Unauthorized');
header('Location: /');

сервер отправляет 302 Found с Location, поэтому не 401 Unauthorized.

Если я сделаю это так:

header('Location: /');
header('HTTP/1.1 401 Unauthorized');

браузер получает как 401 Unauthorized, так и Location, но не перенаправляет.

(IE 9 и Chrome 16 ведут себя одинаково, поэтому я предполагаю, что это правильно)

Может быть, я неправильно использую HTTP? Я бы хотел, чтобы интерфейс моего приложения был одинаковым для всех клиентов: текстовый браузер, современный браузер, вызовы API и т. Д. Текст ответа 401+ сообщит пользователю API, что к чему. Перенаправление полезно для браузера.

Есть (хороший) способ?

Ответы [ 7 ]

27 голосов
/ 08 января 2012

По определению (см. RFC 2616 ), код ответа HTTP 302 является кодом перенаправления.Без этого заголовок местоположения может игнорироваться.

Однако вы можете отправить ответ HTTP 401 и по-прежнему отображать вывод.Вместо того, чтобы перенаправлять пользователя на страницу с ошибкой, вы можете просто написать свой контент, который вы хотите отправить, в теле HTTP в том же запросе.

12 голосов
/ 24 января 2017

Я прихожу очень поздно сюда, но я думал, что добавлю свои два цента.Насколько я понимаю, желание состоит в том, чтобы указать, что у пользователя нет правильной авторизации, и предложить ему войти в систему. По понятным причинам Руди хотел бы вернуть 401 неавторизованным (поскольку пользователю требуется авторизация с помощью какого-либо механизма, например, ведения журнала).в), а также перенаправить их на страницу входа в систему - но это не очень легко сделать и не поддерживается "из коробки" большинством библиотек.Одним из решений является отображение страницы входа в теле ответа 401, как было предложено в другом ответе.Однако позвольте мне взглянуть на это с точки зрения устоявшейся / лучшей практики.

Контрольный пример 1: Facebook

Переход на защищенную страницу Facebook (мой пользовательпрофиль) в то время как выход из системы приводит к ответу 404 Не найдено.Facebook обслуживает страницу общего назначения "эта страница недоступна", которая также включает в себя форму входа.Интересно.Еще более интересно: когда я перехожу на страницу «события», мне подают ответ 302, который пересылается на страницу входа (которая возвращает ответ 200).Поэтому я предполагаю, что их идея состоит в том, чтобы вернуть 302 для страниц, которые мы знаем , существуют, но служат 404 для страниц, которые могут существовать или не существовать (например, для защиты конфиденциальности пользователя).

Контрольный пример 2: Входящие Google

При переходе в папку «Входящие» при выходе из системы возвращается 302 и перенаправляется на страницу входа, аналогичную Facebook.Я не смог выяснить, как сделать свой профиль Google+ личным, поэтому там нет тестовых данных ...

Тестовый пример 3: Amazon.com

Переход кмоя история заказов, когда я вышел из системы, возвращает 302 и перенаправляет меня на страницу входа, как и раньше.У Amazon нет понятия «профильной» страницы, поэтому я тоже не могу протестировать ее здесь.

Подводя итоги тестовых примеров, представляется целесообразным вернуть 302 Found и перейти на страницу входа.если пользователь должен войти в систему (хотя я бы поспорил 303 См. Другое на самом деле более уместно).Это, конечно, только в случае, когда реальный пользователь должен ввести имя пользователя и пароль в HTML-форме.Для других типов аутентификации (например, базовая, API-ключ и т. Д.) 401 Несанкционированный, очевидно, является подходящим ответом.В этом случае нет необходимости пересылать на страницу входа.

6 голосов
/ 08 января 2012

3xx означает, что Redirect
4xx означает, что браузер сделал что-то не так.

Есть причина, по которой коды разделены, как они есть - они не смешиваются;)

4 голосов
/ 08 января 2012

В дополнение к прекрасным ответам Колинка и Дэвида (+ 1), я хотел бы отметить, что вы пытаетесь изменить семантику протокола HTTP, возвращая 401 И сообщая браузеру о перенаправлении.Это не то, как протокол HTTP предназначен для работы, и если вы найдете способ получить этот результат, клиенты HTTP сочтут поведение вашей службы нестандартным.

Либо вы отправляете 401и разрешите браузеру справиться с ним, или вы по-другому справляетесь с ситуацией (например, как предложил один комментатор, перенаправьте на страницу входа или, возможно, на страницу, объясняющую, почему пользователь не имел доступа).

3 голосов
/ 10 марта 2016

Вот чистый способ:

На странице 401 вы можете выбрать «представление» для отправки на основе заголовка «принять» в запросе.

Если принять application/json, то вы можете включить тело:

{"status":401;"message":"Authentication required"}

Если «принять» - text/html, то вы можете включить тело:

<form action="/signin" method="post">
    <!-- bla bla -->
    <input type="hidden" name="redirect" value="[URL ENCODE REQUEST URI]">
</form>

Тогда вы сталкиваетесь с тем же вопросом ... Вы выдаете 200 OK или 302 Found при успешном входе в систему? (видите, что я там делал?)

Если вы можете обрабатывать аутентификацию на любой странице, вы можете просто указать, чтобы действие формы было таким же URL-адресом страницы, но следит за XSS , если вы добавляете пользовательский request_uri в атрибут действия формы.

1 голос
/ 08 января 2012

Вы можете отправить 401, а затем в теле ответа вы можете отправить window.location = 'domain.com'. Однако пользователь будет немедленно перенаправлен, не зная, что произошло 401.

0 голосов
/ 23 декабря 2017

Веб-браузеры не являются клиентами REST. Придерживайтесь отправки статуса 200 с заголовком местоположения и без содержимого тела. 30-кратные перенаправления предназначены для страниц, которые были перемещены. Никакой другой код состояния / заголовок местоположения не должны перенаправляться в веб-браузере.

В качестве альтернативы, ваш веб-сервер может иметь настраиваемые страницы ошибок. Вы можете добавить javascript на страницу ошибки для перенаправления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...