Який код стану http повинен використовуватись, щоб повідомити клієнту, що час очікування закінчився?


80

На веб-сторінці він використовує менеджер з'єднань YUI / джерело даних для надсилання запитів AJAX на сервер, якщо сеанс (який містить інформацію про те, чи був аутентифікований користувач) вже закінчився, відповіді ajax, які можна переглянути лише автентифікованими користувачі повинні повернути код стану http, повідомивши клієнту, що час сеансу вже закінчився, тоді клієнт або просто перенаправляє його на сторінку входу, або запитує, чи хоче він продовжити сеанс.

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

Список кодів стану HTTP з wiki


Ви хочете попередити користувача, що термін дії сеансу закінчується, щоб користувач міг зробити щось для його поновлення? Якщо це так, його повинен обробляти таймер у JavaScript, який спрацьовує до часу очікування сеансу на сервері. На момент відправлення коду стану сервером він вже міг би закінчитися. Таймер також знадобиться, якщо ви автоматично перенаправляєте їх на іншу сторінку, якщо вони залишають сторінку простою.
Джейсон,

8
Чому, звичайно 418! Короткий і міцний ...
Тім Пост

Vaadin використовує 410 Gone, але оскільки він може бути кешований браузером, я б не рекомендував його
sreg

Відповіді:


66

Найкраще, що я можу запропонувати - це код стану HTTP 401 із заголовком WWW-Authenticate.

Проблема з 403 запитами полягає у RFC 2616, яка говорить: "Авторизація не допоможе, і запит НЕ ПОВИНЕН повторюватися." (тобто не має значення, автентифіковані ви чи ні, ви ніколи не отримаєте доступ до цього ресурсу).

Проблема із запитом 401 полягає в тому, що вони "ПОВИННІ включати поле заголовка автентифікації WWW". Як хтось зазначав , не видається порушенням специфікації використання користувацького значення в заголовку WWW-Authenticate.

Я не бачу жодної причини в RFC 2617, чому статус HTTP 401 у поєднанні зі спеціальним заголовком автентифікації WWW, як це, не буде нормальним:

WWW-Authenticate: MyAuthScheme realm="http://example.com"

Специфікація oAuth насправді, здається, робить саме це, оскільки вони рекомендують це (хоча вони, на мою думку, мають дивну інтерпретацію RFC):

WWW-Authenticate: OAuth realm="http://server.example.com/"

RFC, здається, не є САНКЦІОНОВАНИМ, але насправді я не бачу, що це заборонено (воно, здається, не суперечить жодним умовам ПОВИННО або НЕ ПОВИННО, ПОВИННО чи НЕ ПОВИННО).

Я хотів би, щоб був більш конкретний код стану HTTP для таймаутів і для таких речей, як маркери CSRF, недійсні, щоб це було зрозуміліше.


34

Я б порекомендував HTTP 401.

Тоді як 403 в основному говорить: "Вам не дозволено, їдьте і не повертайтеся", 401 говорить: "Ми не знаємо, дозволено вам чи ні, тому що ви не принесли свого посвідчення. дістати і спробувати ще раз ".

Порівняйте визначення Вікіпедії :

HTTP 403 - Запит був законним, але сервер відмовляється відповідати на нього.

HTTP 401 - Подібно до 403 заборонено, але спеціально для використання, коли автентифікація можлива, але не вдалася або ще не надана.


3
401 призначений для аутентифікації HTTP . RFC 2616 говорить response MUST include a WWW-Authenticate header field. Отже, неправильно надсилати цей код без поля заголовка WWW-Authenticate .
toxalot

19

Що стосується 419 - це не є стандартним, але опис у Вікіпедії, здається, відповідає:

419 Час очікування автентифікації

419 Час очікування автентифікації, який не є частиною стандарту HTTP, означає, що термін дії автентифікації минув. Він використовується як альтернатива 401 Unauthorized, щоб відрізняти клієнтів, яким інакше автентифіковано відмовлено у доступі до певних ресурсів сервера.


14
Будь-яка ідея, звідки це береться (крім Вікіпедії)? Якщо цього немає в офіційному RFC, хто його визначив?
анаксимандр

5
Здається, його також видалено з цієї вікі-сторінки
Салем Оуердані

Це не є частиною специфікації, вона також не доступна в Java HttpServletResponse@John, якщо ви знаєте якесь інше надійне джерело, краще посилатися на нього.
Вішрант,

Здається, мене використовують лише у PHP Laravel
TroySteven

12

Я вважаю, що відповідним кодом буде 403 / Заборонено. Немає таких, які безпосередньо пов’язані із сесіями.


1
Абсолютно це правильна відповідь. Оскільки сеанс закінчився, запит заборонено, тому це найкращий вибір.
marcc

3
403 говорить клієнтові (в основному) "Не робіть цього ще раз, якщо ви не зміните свій запит", але якби сеанс був встановлений, ніяких змін не потрібно. Крім того, ви не можете нічого зробити з (поточним) запитом на відновлення сесії в більшості випадків.
Tim Post

1
Точно так! Я думаю, 401 було б краще, але для цього потрібна аутентифікація HTTP. Я думаю, що це вимагає нового статусу на рівні 401 + 303 (так, очевидно, 704), що означає "Не авторизований, див. Інші для отримання дозволу". Окрім того, що воно є більш семантично правильним, воно також може бути рішенням HTTP для перенаправлення батута, в основному "йди сюди, тоді, коли ти повернешся, ми спробуємо це ще раз", щоб сторінка входу могла бути агностичною щодо пункт призначення.
Ентоні,

5
Я не можу погодитися з цим, RFC 2616 прямо заявляє, що запити, результатом яких є відповідь 403 "НЕ ПОВИНЕН повторюватися" клієнтом, і що "авторизація не допоможе".
Іен Коллінз

5
authorization will not help- Я вважаю, що означає, що аутентифікація HTTP не допоможе. Що правильно. Надсилання заголовка авторизації нічого не змінить. Ні 401, ні 403 не є ідеальними, але, на мою думку, 403 є кращим, ніж 401. 401 неправильний для таймауту сеансу, оскільки RFC 2616 прямо вказує client MAY repeat the request with a suitable Authorization header field. Але в цьому випадку клієнт НЕ ПОВИНЕН повторити запит (принаймні, не без проміжного кроку). На жаль, ми не можемо повідомити останню частину за допомогою коду стану.
toxalot

11

По правді кажучи, не існує стандартного коду стану HTTP для часу очікування сеансу. Сеанси реалізовані на рівні програми, а не на транспортному рівні HTTP.

Існує спеціальний код стану, який Microsoft використовував для часу очікування сеансу: 599, або просто складіть власний код стану в діапазоні 5xx.

З Вікі з кодами стану:

599 Помилка таймауту підключення до мережі (невідомо) Цей код стану не вказаний у жодних RFC, але використовується проксі-серверами Microsoft Corp. HTTP для сигналізації про час очікування мережевого підключення позаду проксі для клієнта перед проксі.

Я використовую власний код стану 599 для часу очікування сеансу, а потім перевіряю його у відповіді AJAX.


3
Час очікування мережевого з'єднання сильно відрізняється від часу очікування сеансу. Якщо ви збираєтеся використовувати код з розширенням Microsoft, чому б не використати 440 Login Timeout (Microsoft)відповідно з відповіддю Фейсала МЕК в
toxalot

Ця сторінка Вікіпедії про 599 була помилковою і не мала жодного цитування. Очевидно, раніше говорили, що проксі-сервери Microsoft піднімають 599 за час очікування мережі, але я також не міг знайти доказів цього.
Gareth Davidson,

11

Відповідно до посилання Вікіпедії на коди статусу Http, надані Бобо:

440 Login Timeout (Microsoft)

    A Microsoft extension. Indicates that your session has expired.

Чи є повідомлення апач може перетворити цей статус повернення до 500, так як це зробив мій - stackoverflow.com/questions/17735514 / ...
commonpike

Мені подобається це рішення для середовищ ASP.NET.
TroySteven

9

Коли ви публікуєте посилання, у цьому посиланні я знайшов цей код стану HTTP 440 . Ви можете використовувати код статусу HTTP 440 для закінчення терміну дії сеансу.

440 Час очікування входу

 The client's session has expired and must log in again.

401 Несанкціоновано ми можемо використовувати, коли облікові дані користувача невірні. або маркер автентифікації, переданий у заголовку, недійсний.

403 Заборонено, ми можемо використовувати це, коли користувач не має конкретного дозволу на запитуваний ресурс.

Отже, на мою думку, ми повинні використовувати 440 Час очікування для входу .


2

Технічно прийнята відповідь, звичайно, є правильною: якщо ви вже точно знаєте, що збираєтеся не виконати запит, і запитуєте, який код відмови повернути, то відповідним є HTTP 401 "Несанкціонований (неавторизований)", щоб запросити повторну автентифікацію.

Але перш за все, запитайте себе: чи не можна пропустити запит?

Враховуйте, що користувач може просто відвідувати загальнодоступну сторінку вашого веб-сайту, і в цьому випадку ви збираєтеся ляпати їх по обличчю написом "Несанкціоновано!" повідомлення та вимагати від них повторної автентифікації, щоб побачити сторінку, яку вони зазвичай могли б бачити без автентифікації. Це не круто.

Моя порада - ігнорувати той факт, що маркер сеансу невідомий, а просто продовжувати генерувати новий маркер сеансу та створювати для нього новий сеанс. Початковий стан сеансу, звичайно, буде "ще не аутентифікованим", тому, якщо користувач намагається отримати доступ до непублічної сторінки, сторінка подбає про те, щоб він отримав HTTP 401 "Несанкціонований (неаутентифікований) "і повинен пройти автентифікацію. Але якщо користувач потрапляє на загальнодоступну сторінку, він не помітить нічого іншого.


0

Я б використав відповідь переадресації 302 із заголовком "Location", що спрямовує на шлях до ресурсу, наприклад "/ auth-required"

Клієнт може направити шлях ресурсу до модального за допомогою форми логіна / пароля, уникаючи перекладу користувача на іншу сторінку.


-3

Для запитів, що не стосуються Ajax, я використовую переспрямування 302.

Для запитів Ajax я використовую 200 для відомих помилок. Таким чином я можу скористатися об’єктом даних. Я вважаю, що з об'єктом даних легше працювати, ніж аналізувати jqXHR для отримання інформації. І тоді мені не потрібно турбуватися про те, який код стану HTTP намагатись переназначити для моєї ситуації.

Приклад jQuery:

$.ajax({
    //send data to server
})
.done(function(data, textStatus, jqXHR) {
    if (data.success) {
        //then process return data
    }
    else {
        //get error type or message from data object
        //could use custom error codes
    }
})
.fail(function(jqXHR, textStatus, errorThrown) {
    //handle unknown errors
});

6
Небажання аналізувати відповідь не є вагомою причиною відхилятися від специфікації HTTP, особливо коли ви можете просто JSON.parse (responseText).
Девід Нельсон,

Я не думаю, що використання коду відповіді 200 в цьому випадку відхиляється від специфікації HTTP, оскільки запит був технічно успішним на транспортному рівні. Для мене час очікування сеансу подібний до помилок форми, коли я повертаю зручне повідомлення про помилку. Розбіжності, висловлені у відповідях на це запитання, однозначно вказують на те, що специфікація HTTP не надає прийнятого в галузі коду відповідей на час очікування сеансу. Як можна відступити від специфікації, яка не існує?
toxalot

-4

Код 408. "Час очікування запиту" здається ідеальним - RFC 2616 пояснює, що це означає

Клієнт не подав запит протягом часу, коли сервер був готовий до очікування.

тобто, саме "тайм-аут", як вам потрібно!


4
А, але погляньте на решту визначення: "Клієнт може повторити запит без змін у будь-який пізніший час". "Без змін" означатиме, що новий сеанс може бути створений простим перезавантаженням / оновленням запиту. У більшості випадків, коли використовується аутентифікація, спочатку користувачеві доведеться ввійти знову.
AJ.

@AJ, звичайно, повторний запит може зіткнутися із завданням автентифікації (код HTTP 401) - не бачите нічого в специфікаціях HTTP, що забороняє це , чи можете ви вказати на що-небудь?
Алекс Мартеллі,

5
408 каже клієнту, що їм слід просто спробувати повторно подати запит як є, що, очевидно, не може працювати, якщо сеанс закінчився.
Tim Post

4
408 - це час очікування "запиту", а не час очікування сеансу. Це означає, що розетка була встановлена, але тривала занадто довго. Цей сайт добре пояснює це: checkupdown.com/status/E408.html
Бред Купіт,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.