Що таке правильний код статусу HTTP під час переадресації на сторінку входу?


133

Якщо користувач не входить у систему та намагається отримати доступ до сторінки, яка потребує входу, який правильний код статусу HTTP для переадресації на сторінку входу?

Я запитую, оскільки жоден із 3хX кодів відповідей, встановлених W3C, здається, не відповідає вимогам:

10.3.1 300 декількох варіантів

Запитаний ресурс відповідає будь-якому з набору представлень, кожне зі своїм конкретним місцеположенням, і надається керована агентом інформація про переговори (розділ 12), щоб користувач (або агент користувача) міг вибрати бажане представлення та перенаправити його запит до цього місця.

Якщо це не запит HEAD, відповідь ДОЛЖЕН би включати сутність, що містить перелік характеристик ресурсів та місцеположення, з яких користувач або користувальницький агент можуть вибрати найбільш відповідний. Формат сутності визначається типом носія, вказаним у полі заголовка Content-Type. Залежно від формату та можливостей

користувальницький агент, вибір найбільш відповідного вибору МОЖЕ проводитися автоматично. Однак ця специфікація не визначає жодного стандарту для такого автоматичного вибору.

Якщо сервер має кращий вибір представлення, він ДОЛЖЕН би включити конкретний URI для цього представлення в полі Location; користувацькі агенти МОЖЕ використовувати значення поля Location для автоматичного перенаправлення. Ця відповідь є кешованою, якщо не вказано інше.

10.3.2 301 Переміщено постійно

Запитаному ресурсу присвоєно новий постійний URI, і будь-які майбутні посилання на цей ресурс ДОЛЖНІ використовувати один з повернених URI. Клієнти, що мають можливості редагування посилань, повинні, коли це можливо, автоматично перенаправляти посилання на URI-запит на одну або декілька нових посилань, повернених сервером. Ця відповідь є кешованою, якщо не вказано інше.

Новий постійний URI повинен бути вказаний полем відповіді у відповіді. Якщо метод запиту не був 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. Оскільки перенаправлення може бути змінено з певного разу, клієнт ДОЛЖЕН би використовувати URI-запит для майбутніх запитів. Ця відповідь є кешованою лише тоді, коли вона вказана в полі заголовка Cache-Control або Expires.

Тимчасовий URI повинен бути вказаний полем Location у відповіді. Якщо метод запиту не був 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 для значення поля Location незалежно від оригінального методу запиту. Коди статусу 303 та 307 додані для серверів, які хочуть однозначно зрозуміти, яка реакція очікується від клієнта.

10.3.4 303 Див. Інше

Відповідь на запит можна знайти під іншим URI, і ДОЛЖЕН бути отриманий за допомогою методу GET на цьому ресурсі. Цей метод існує головним чином, щоб дозволити виводу сценарію, активованого POST, перенаправити агент користувача на обраний ресурс. Новий 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 для оновлення запису кешу, кеш ОБОВ'ЯЗКОВО оновити запис для відображення будь-яких нових значень поля, поданих у відповіді.

10.3.6 305 Використовуйте проксі

До запитуваного ресурсу ОБОВ'ЯЗКОВО бути доступним через проксі-сервер, вказаний у полі Location. Поле Location дає 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. Оскільки перенаправлення МОЖЕ бути змінено в певний час, клієнт ДОЛЖЕН продовжувати використовувати URI-запит для майбутніх запитів. Ця відповідь є кешованою лише тоді, коли вона вказана в полі заголовка Cache-Control або Expires.

Тимчасовий URI повинен бути вказаний полем Location у відповіді. Якщо метод запиту не був HEAD, суть відповіді ДОЛЖНА містити коротку примітку гіпертексту з гіперпосиланням на нові URI (s), оскільки багато користувальницьких агентів, що передують HTTP / 1.1, не розуміють стану 307. Тому примітка ДОЛЖНА містити інформацію, необхідну користувачеві для повторення початкового запиту на новому URI.

Якщо код статусу 307 отримано у відповідь на запит, відмінний від GET або HEAD, агент користувача НЕ повинен автоматично перенаправляти запит, якщо він не може бути підтверджений користувачем, оскільки це може змінити умови, за яких запит був виданий.

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

Оновлення та висновок:

HTTP 302 кращий, оскільки, як відомо, найкраща сумісність з клієнтами / браузерами.


1
Я б сказав, що абсолютно книжковим способом було б повернення 401 та сторінки входу без перенаправлення, але я не впевнений, які у вас варіанти.
Нік Крейвер

1
@Nick хороший момент, але я б побоювався побічних ефектів від цього, якби будував класичну систему входу.
Пекка

1
@Pekka - Цілком погоджуюся, це залежить від того, на якій платформі це працює, як все, що можна чітко обробляти, також, якщо це грає Інтранет проти Інтернету, я вважаю ... ти зазвичай робиш аутентифікацію по-іншому в інтранеті, принаймні в моєму досвіді.
Нік Крейвер

@ Nick З 401 "Відповідь ОБОВ'ЯЗКОВО включає поле заголовка WWW-Authenticate" - Як я можу поєднати це з базою даних MySQL? Хіба AuthType Basic та Digest не обмежені файлами конфігурації apache, такими як .htpassword тощо ...?
Відар Вестнес

Я хочу користувацьку сторінку входу, а не основне діалогове вікно браузера з запитом імені користувача та пароля ...
Vidar Vestnes

Відповіді:


66

Я б сказав 303 див. Інші 302 Знайдено:

Запитаний ресурс тимчасово знаходиться під іншим URI. Оскільки перенаправлення може бути змінено з певного разу , клієнт ДОЛЖЕН би використовувати URI-запит для майбутніх запитів. Ця відповідь є кешованою лише тоді, коли вона вказана в полі заголовка Cache-Control або Expires.

на мою думку, найбільше підходить для сторінки входу. Я спочатку вважав, 303 see otherщо буде так само добре. Поміркувавши, я б сказав , що 302 Foundбільше підходить , тому що запитуваний ресурс був знайдений, там тільки одна сторінка , щоб пройти , перш ніж вона може бути доступна. Відповідь не кешується за замовчуванням, що також добре.


4
Я погоджуюся, але я думаю, що 302 Знайдено вказує на те, що ресурс був знайдений лише під іншою URL-адресою. Вих. Я хочу передати / мої повідомлення / відповідь сервера з номером 302, оскільки "сьогодні" мої повідомлення розміщені в "/ логіні /" (замість "/ повідомлень /") ... я використовую 302, але я не відчуваю контекст відповідає 100% відповідності. Оскільки сторінка входу - це інший ресурс і не має того самого вмісту, що і запитуваний.
Відар Вестнес

2
@PHP_Jedi правда. 303 може бути більш підходящим з цієї точки зору. Однак 302 є більш надійним з точки зору сумісності клієнтів.
Пекка

1
Так, я думаю, що 303 може краще відповідати контексту, оскільки в ньому йдеться про "Відповідь на запит можна знайти під іншим URI". Це говорить мені про те, що в іншому URI не той самий ресурс, а лише відповідь на цей запит.
Відар Вестнес

3
@PHP_Jedi Я не впевнений, чи варто вкладати стільки часу в це. Обидва клієнта і сервера в HTTP світі повинні бути вкрай ліберальним і відмовостійка в будь-якому випадку, так що не буде ніякої реальної різниці , чи використовуєте ви 302або 303, за винятком того, що 302краще відомо. Я вважаю, що рівень деталізації похвальний, і завжди добре все виправити, але занадто багато зусиль може бути марним у цій конкретній області.
Pekka

28
FYI: Google випускає 302-і
Девід Мердок

51

Це неправильне використання механізму перенаправлення HTTP. Якщо користувач не має авторизації, то ваша програма повинна повернутися 401 Unauthorized. У випадку, якщо користувач має авторизацію, але не має доступу до запитуваного ресурсу, його 403 Forbiddenнеобхідно повернути.

Ви повинні зробити переспрямування на стороні клієнта, наприклад, через javascript. код статусу для переадресації, оскільки необхідна авторизація не існує . Використання 30x для цього не відповідає HTTP.

Як думати про коди статусу HTTP від ​​Марка Ноттінгема

401 Несанкціонований запускає механізм аутентифікації запиту HTTP.

401 Unauthorizedкод статусу вимагає наявності WWW-Authenticateзаголовка, який підтримує різні типи аутентифікації:

WWW-аутентифікат: <type> realm = <realm>

Носій, OAuth, Basic, Digest, Cookie тощо


20
401 може не відповідати в деяких випадках як A server generating a 401 (Unauthorized) response MUST send a WWW-Authenticate header field( RFC ), і не всі системи входу використовують це заголовок.
starbeamrainbowlabs

6
Припустимо, ви оновлюєте захищену сторінку; клієнтська javascript не матиме жодних змін для виклику, і браузер відкриє вікно входу, а не перенаправляє користувача на сторінку входу, тому єдиним способом є використання коду 30x.
Клод Бріссон

2
Golang не може використовувати 401 для перенаправлення. Це означає, що ми повинні використовувати 30 * для переадресації.
EIMEI

4
@EIMEI, слідуючи вашим міркуванням, якщо інша мова чи бібліотека змушують вас використовувати 401, то Інтернет буде приречений. Моя думка: те, що ви говорите, вказує на проблему з Golang (хоча мені здається, що це дивно, що вона мала б такий дизайн, щоб унеможливити надсилання 401s!)
Грег,

2
@starbeamrainbowlabs У заголовку WWW-Authenticate є опція HTTP-аутентифікації на основі файлів cookie. Дивіться: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef

12

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

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

Мета цього заголовка саме в цьому. Але, замість перенаправлення на сторінку входу, правильний процес буде чимось таким:

  • Користувач не ввійшов у систему, спробуйте отримати доступ до сторінки з обмеженням для входу.
  • система ідентифікує користувача, не реєструється
  • система повертає заголовок HTTP 401, І відображає форму входу в тій самій відповіді (не перенаправлення).

Це хороша практика, як надання корисної сторінки 404 із посиланнями на мапу сайту та формою пошуку, наприклад.

Побачимося.


20
RFC зазначає: "Відповідь ОБОВ'ЯЗКОВО включати поле заголовка WWW-Authenticate (розділ 14.46), що містить виклик, застосовний до запитуваного ресурсу." Відповідь 401 дійсно застосовно лише при використанні схеми аутентифікації HTTP.
bshacklett

4
У цьому випадку 403 було б краще, оскільки в ньому зазначається, що доступ просто заборонений, а заголовок авторизації не допоможе
olanod

@bshacklett WWW-Authenticate можна використовувати разом із багатьма схемами аутентифікації (наприклад, Bearer, OAuth). Дивіться developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… та iana.org/assignments/http-authschemes/http-authschemes.xhtml
filip26

У заголовку WWW-аутентифікату є варіант для HTTP-аутентифікації на основі файлів cookie. Дивіться: tools.ietf.org/html/draft-broyer-http-cookie-auth-00
aef
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.