Что такое правильный код состояния HTTP при перенаправлении на страницу входа?

Когда пользователь не входит в систему и пытается получить доступ к странице, требующей входа в систему, каков правильный код состояния HTTP для перенаправления на страницу входа?

Я спрашиваю, потому что ни один из кодов ответов 3xx, установленных W3C, похоже, соответствует следующим требованиям:

10.3.1 300 Множественный выбор

Запрошенный ресурс соответствует любой из множества представлений, каждый со своим конкретным местоположением, и управляемые агентом переговоры информация (раздел 12) при условии, что пользователь (или пользователь агент) может выбрать предпочтительный представительство и перенаправление его запрос в это место.

Если это не был запрос HEAD, ответ ДОЛЖЕН включать объект содержащий список ресурсов характеристик и местоположения от которые пользователь или пользователь может выберите наиболее подходящий. формат сущности тип носителя, указанный в Content-Type поле заголовка. В зависимости от формат и возможности

пользовательский агент, выбор наиболее подходящий выбор МОЖЕТ быть выполнен автоматически. Однако это спецификация не определяет стандарт для такого автоматического выбора.

Если сервер имеет предпочтительный выбор представления, ДОЛЖНЫ включать конкретный URI для этого представление в поле "Местоположение" ; пользовательские агенты МОГУТ использовать поле "Место" значение для автоматического перенаправления. Эта ответ кэшируемый, если не указано в противном случае.

10.3.2 301 Перемещено на постоянной основе

Запрошенный ресурс назначил новый постоянный URI и любой будущие ссылки на этот ресурс СЛЕДУЕТ использовать один из возвращенных URI. Клиенты с возможностями редактирования ссылок должна автоматически перерисовываться ссылки на Request-URI на один или больше возвращенных ссылок сервером, где это возможно. Эта ответ кэшируемый, если не указано в противном случае.

Новый постоянный URI ДОЛЖЕН быть предоставлен по полю Location в ответе. Если метод запроса не был HEAD, субъект ответа СЛЕДУЕТ содержат короткую гипертекстовую заметку с гиперссылка на новый URI (ы).

Если код статуса 301 принят ответ на запрос, отличный от GET или HEAD, пользовательский агент НЕ ДОЛЖЕН автоматически перенаправить запрос если это не может быть подтверждено пользователя, поскольку это может изменить условия, при которых выдан.

  Note: When automatically redirecting a POST request after
  receiving a 301 status code, some existing HTTP/1.0 user agents
  will erroneously change it into a GET request.

10.3.3 302 Найдено

Запрошенный ресурс временно под другим URI. Поскольку перенаправление может быть изменено иногда клиент ДОЛЖЕН продолжать использовать Request-URI для будущие запросы. Этот ответ только кэшируемый, если указано Cache-Control или Expires.

Временный URI ДОЛЖЕН быть предоставлен поле "Местоположение" в ответе. Если метод запроса не был HEAD, субъект ответа СЛЕДУЕТ содержат короткую гипертекстовую заметку с гиперссылка на новый URI (ы).

Если код статуса 302 получен в ответ на запрос, отличный от GET или HEAD, пользовательский агент НЕ ДОЛЖЕН автоматически перенаправить запрос если это не может быть подтверждено пользователя, поскольку это может изменить условия, при которых выдан.

  Note: RFC 1945 and RFC 2068 specify that the client is not allowed
  to change the method on the redirected request.  However, most
  existing user agent implementations treat 302 as if it

были 303       ответ, выполняющий GET в поле значения местоположения независимо от       исходного метода запроса. Коды состояния 303 и 307 имеют       был добавлен для серверов, которые хотят однозначно       ожидаемая реакция клиента.

10.3.4 303 См. Другие

Ответ на запрос может быть найденный под другим URI и СЛЕДУЕТ извлекаться с использованием метода GET на этот ресурс. Этот метод существует прежде всего, чтобы обеспечить выход POST-активирован script для перенаправления пользовательский агент к выбранному ресурсу. новый URI не является заменой ссылки для первоначально запрошенного ресурса. Ответ 303 НЕ ДОЛЖЕН быть кэширован, но ответ на второй (перенаправленный) запрос может быть кэшируется.

Разный URI ДОЛЖЕН быть предоставлен поле "Местоположение" в ответе. Если метод запроса не был HEAD, субъект ответа СЛЕДУЕТ содержат короткую гипертекстовую заметку с гиперссылка на новый URI (ы).

  Note: Many pre-HTTP/1.1 user agents do not understand the 303
  status. When interoperability with such clients is a concern, the
  302 status code may be used instead, since most user agents react
  to a 302 response as described here for 303.

10.3.5 304 Не изменено

Если клиент выполнил условный запрос GET и доступ разрешено, но документ не был изменен, сервер ДОЛЖЕН ответить с этим кодом состояния. 304 ответ НЕ ДОЛЖЕН содержать тело сообщения, и, следовательно, всегда заканчивается первой пустой строкой после полей заголовка.

Ответ ДОЛЖЕН включать следующие поля заголовка:

  - Date, unless its omission is required by section 14.18.1 If a

сервер времени без синхронизации подчиняется этим правила, а также прокси и клиенты их собственная дата на любой ответ полученных без одного (как уже указанный в [RFC 2068], раздел 14.19), кеши будут работать правильно.

  - ETag and/or Content-Location, if the header would have been sent
    in a 200 response to the same request
  - Expires, Cache-Control, and/or Vary, if the field-value might
    differ from that sent in any previous response for the same
    variant If the conditional GET used a strong cache validator (see

раздел 13.3.3), ответ СЛЕДУЕТ НЕ включать другие заголовки объектов. В противном случае (т.е. Условное GET использовал слабый валидатор), ответ НЕ ДОЛЖНО включать другие заголовки объектов; это предотвращает несоответствие между кэшированных сущностей и обновленных заголовки.

Если ответ 304 указывает объект в настоящее время не кэшируется, затем кеш ДОЛЖЕН игнорировать ответ и повторять запрос без условного обозначения.

Если кеш использует принятый 304 ответ на обновление записи в кеше, cache ДОЛЖНО обновлять запись для отражения любые новые значения полей, приведенные в Ответ.

10.3.6 305 Использовать прокси

Запрошенный ресурс ДОЛЖЕН быть доступ через посредство, предоставленный поле "Место". Поле "Местоположение" дает URI прокси. получатель должен повторить это один запрос через прокси. 305 ответы должны быть созданы только исходных серверов.

  Note: RFC 2068 was not clear that 305 was intended to redirect a
  single request, and to be generated by origin servers only.  Not
  observing these limitations has significant security consequences.

10.3.7 306 (не используется)

Код статуса 306 использовался в предыдущая версия спецификации, больше не используется, и код зарезервирован.

10.3.8 307 Временная переадресация

Запрошенный ресурс временно под другим URI. Поскольку перенаправление МОЖЕТ быть изменено иногда клиент ДОЛЖЕН продолжать использовать Request-URI для будущие запросы. Этот ответ только кэшируемый, если указано Cache-Control или Expires.

Временный URI ДОЛЖЕН быть предоставлен поле "Местоположение" в ответе. Если метод запроса не был HEAD, субъект ответа СЛЕДУЕТ содержат короткую гипертекстовую заметку с гиперссылку на новый URI (ы), поскольку многие пользовательские агенты pre-HTTP/1.1 не понять статус 307. Следовательно, примечание ДОЛЖНО содержать информацию, необходимую пользователю для повторите первоначальный запрос на новый URI.

Если код статуса 307 получен в ответ на запрос, отличный от GET или HEAD, пользовательский агент НЕ ДОЛЖЕН автоматически перенаправить запрос если это не может быть подтверждено пользователя, поскольку это может изменить условия, при которых выдан.

Я использую 302, пока не найду правильный ответ.

Обновление и заключение:

HTTP 302 лучше, так как он, как известно, имеет лучшую совместимость с клиентами/браузерами.

Ответ 1

Я бы сказал 303 см. другие 302 Найдено:

Запрошенный ресурс временно находится под другим URI. Поскольку перенаправление может быть изменено в случае, клиенту ДОЛЖНО продолжать использовать Request-URI для будущих запросов. Этот ответ доступен только для кэширования, если указано полем Cache-Control или Expires.

подходит к странице входа наиболее близко, на мой взгляд. Я изначально считал 303 see other, который будет работать так же хорошо. После некоторого раздумья, я бы сказал, что 302 Found более подходит, потому что запрошенный ресурс найден, есть только другая страница, чтобы пройти, прежде чем к ней можно будет получить доступ. Ответ не получает кэширование по умолчанию, что тоже хорошо.

Ответ 2

Это неправильное использование механизма перенаправления HTTP. Если пользователь не авторизовался, ваше приложение должно вернуть 401 Unauthorized. В случае, если пользователь авторизован, но не имеет доступа к запрашиваемому ресурсу, необходимо вернуть 403 Запрещенный.

Вы должны сделать перенаправление на стороне клиента, например. по javascript. код статуса для перенаправления, поскольку требуемая авторизация отсутствует. Использование 30x для этого не соответствует HTTP.

Ответ 3

Я думаю, что подходящим решением является заголовок HTTP 401 (Not Authorized).

http://en.wikipedia.org/wiki/HTTP_codes#4xx_Client_Error

Цель этого заголовка - именно это. Но вместо перенаправления на страницу входа в систему правильный процесс будет выглядеть примерно так:

  • Пользователь, не зарегистрированный, пытается получить доступ к странице с ограниченным доступом.
  • система идентифицирует пользователя не регистрируется
  • возвращает заголовок HTTP 401 и отображает форму входа в тот же ответ (а не перенаправление).

Это хорошая практика, например, предоставление полезной страницы 404 с ссылками на карту сайта и формой поиска.

Увидимся.

Ответ 4

У меня были редкие случаи, когда браузер Firefox кэшировал перенаправление 302. Именно по этой причине я использую 307 для страниц входа и, например, перенаправляет на новую статью/сообщение/комментарий/и т.д.

Если вы используете 302, не забудьте дважды проверить, что кеширование отключено:

header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-cache');
header('Pragma: no-cache');
header('Cache-Control: post-check=0, pre-check=0', false);