HTTP 401 - jaka jest odpowiednia wartość nagłówka WWW-Authenticate?

109

Aplikacja, nad którą obecnie pracuję, ma wartość limitu czasu sesji. Jeśli użytkownik nie wchodził w interakcję dłużej niż ta wartość, podczas następnej strony, którą spróbuje załadować, zostanie poproszony o zalogowanie.

Wszystkie żądania są kierowane przez ten mechanizm, który obejmuje wywołania AJAX. Pierwotnie wysyłaliśmy nagłówek 200 ze stroną logowania, co wprowadza pewne problemy z AJAX, ponieważ kod jest uruchamiany po wysłaniu odpowiedzi 200, a większość danych odsyłanych z tych wywołań RPC to JSON lub surowy JavaScript, który jest oceniany (nie zapytaj: |).

Zasugerowałem, że 401 jest lepszy, ponieważ nasz parser JSON nie będzie próbował zużywać strony logowania HTML .. :)

Po przeczytaniu specyfikacji , jednak zauważyłem, że WWW-Authenticatepole musi być również wysłana.

Jaka jest dobra wartość tego pola? Czy Application Loginwystarczy?

Will Morgan
źródło

Odpowiedzi:

67

Wskazując HTTP Basic Authentication zwracamy coś takiego:

WWW-Authenticate: Basic realm="myRealm"

Podczas gdy Basicjest to schemat, a reszta jest bardzo zależna od tego schematu. W tym przypadku dziedzina po prostu dostarcza przeglądarce literał, który może zostać wyświetlony użytkownikowi po wyświetleniu monitu o identyfikator użytkownika i hasło.

Oczywiście nie używasz jednak Basic, ponieważ nie ma sensu wygasanie sesji, gdy używane jest Basic Auth. Zakładam, że używasz jakiejś formy uwierzytelniania opartego na formularzach.

Jak pamiętam, Windows Challenge Response używa innego schematu i innych argumentów.

Sztuczka polega na tym, że przeglądarka musi określić, jakie schematy obsługuje i jak na nie odpowiada.

Wydaje mi się, że jeśli używasz uwierzytelniania opartego na formularzach, pozostań przy stronie ponownego logowania 200 +, ale dodaj niestandardowy nagłówek, który przeglądarka zignoruje, ale twój AJAX może zidentyfikować.

Aby uzyskać naprawdę dobre wrażenia użytkownika + AJAX, pobierz skrypt, aby zawiesił się na żądaniu AJAX, które wykryło wygaśnięcie sesji, uruchom żądanie ponownego logowania za pośrednictwem wyskakującego okienka, a jeśli się powiedzie, ponownie prześlij oryginalne żądanie AJAX i kontynuuj normalnie.

Unikaj oszustwa, który powoduje, że skrypt trafia na stronę co 5 minut, aby utrzymać sesję przy życiu, ponieważ po prostu pokonuje punkt wygaśnięcia sesji.

Inną alternatywą jest nagranie żądania AJAX, ale jest to kiepskie wrażenia użytkownika.

Swanny
źródło
2
Dzięki kolego, zamiast tego używam teraz 403, ponieważ nie jest to przekierowanie i dosłownie zawiera formularz logowania w miejscu oryginalnej strony. Lepiej też pasuje do specyfikacji W3. Jednak dzięki za informację.
Will Morgan
2
Zobacz tę odpowiedź o tym, jak nadal możesz korzystać z HTTP 401: stackoverflow.com/questions/928874/ ...
lanoxx
Tak, przypuszczam, że po prostu umieść wszystko w nagłówku WWW-Authenticate. Inną odpowiedzią w podobnym duchu jest stackoverflow.com/a/1088127/689161. Lub po prostu narusz specyfikację i nie zawracaj sobie głowy wysyłaniem nagłówka (przynajmniej kilka witryn to robi); 401 jest nadal bardziej odpowiednie niż 403.
gengkev
Nie jestem pewien, czy mógłbym „po prostu umieścić cokolwiek” w nagłówku WWW-Authenticate, ponieważ nie mam pewności, czy żądanie jest obsługiwane przez mój plik AJAX czy przeglądarkę. Poza tytułem tego pytania, biorąc pod uwagę szczegóły sugerujące uwierzytelnianie oparte na formularzach, w ogóle nie wysyłałbym nagłówka WWW-Authenticate. Dzieje się tak, ponieważ nie proszę przeglądarki o udział w wyzwaniu uwierzytelniania / poświadczeń. Chcę tylko, aby pokazywał formularz, który akurat jest formularzem logowania, ale z czymś, czego ajax może użyć do zidentyfikowania, jest to formularz logowania, więc może obsługiwać go inaczej, jak powyżej.
Swanny
Powinieneś wymyślić schemat authn do użycia z nagłówkiem. Wtedy przeglądarka się nie zaangażuje, ponieważ nie zrozumie schematu. Niektórzy klienci są zdenerwowani lub zdezorientowani, jeśli nie uwzględnisz nagłówka.
KayEss
-7

Po przekroczeniu limitu czasu sesji użytkownika odsyłam kod stanu HTTP 204. Zwróć uwagę, że stan HTTP 204 nie zawiera treści. Po stronie klienta robię to:

xhr.send(null);
if (xhr.status == 204) 
    Reload();
else 
    dropdown.innerHTML = xhr.responseText;

Oto funkcja Reload ():

function Reload() {
    var oForm = document.createElement("form");
    document.body.appendChild(oForm);
    oForm.submit();
    }
Smurfling
źródło
6
Dlaczego używasz protokołu HTTP 204? developer.mozilla.org/en-US/docs/Web/HTTP/Status/204
Will Morgan