HTTP 401 - o que é um valor de cabeçalho WWW-Authenticate apropriado?

109

O aplicativo em que estou trabalhando no momento tem um valor de tempo limite de sessão. Se o usuário não interagir por mais tempo do que esse valor, na próxima página que tentar carregar, será solicitado que ele faça login.

Todas as solicitações feitas são roteadas por meio desse mecanismo, que inclui chamadas AJAX. Originalmente, estávamos enviando um cabeçalho 200 com a página de login, o que introduz alguns problemas com AJAX, uma vez que o código é executado se uma resposta 200 for enviada, e a maioria dos dados enviados de volta dessas chamadas RPC é JSON ou JavaScript bruto que é avaliado (não pergunte: |).

Sugeri que um 401 é melhor, já que nosso analisador JSON não tentará consumir uma página de login HTML .. :)

Ao ler a especificação , porém, percebi que o WWW-Authenticatecampo também deve ser enviado.

Qual é um bom valor para este campo? Será o Application Loginsuficiente?

Will Morgan
fonte

Respostas:

67

Ao indicar a autenticação básica HTTP, retornamos algo como:

WWW-Authenticate: Basic realm="myRealm"

Considerando que Basicé o esquema e o restante é muito dependente desse esquema. Nesse caso, o domínio apenas fornece ao navegador um literal que pode ser exibido ao usuário ao solicitar o ID do usuário e a senha.

Obviamente, você não está usando o Basic, pois não faz sentido ter uma sessão expirada quando o Basic Auth é usado. Presumo que você esteja usando alguma forma de autenticação baseada em formulários.

Da lembrança, o Windows Challenge Response usa um esquema diferente e argumentos diferentes.

O truque é que depende do navegador determinar quais esquemas ele suporta e como responde a eles.

Minha intuição, se você está usando autenticação baseada em formulários, é permanecer na página 200 + de relogin, mas adicionar um cabeçalho personalizado que o navegador irá ignorar, mas que o AJAX pode identificar.

Para obter uma experiência realmente boa de Usuário + AJAX, faça com que o script mantenha a solicitação AJAX que encontrou a sessão expirada, dispare uma solicitação de relogin por meio de um pop-up e, em caso de sucesso, reenvie a solicitação AJAX original e continue normalmente.

Evite o cheat que apenas faz com que o script chegue ao site a cada 5 minutos para manter a sessão ativa, pois isso acaba com o ponto de expiração da sessão.

A outra alternativa é gravar a solicitação AJAX, mas isso é uma experiência do usuário ruim.

Swanny
fonte
2
Obrigado amigo, agora estou usando um 403, pois não é um redirecionamento e inclui literalmente o formulário de login no lugar da página original. Também corresponde melhor à especificação W3. Obrigado pela informação no entanto.
Will Morgan
2
Veja esta resposta sobre como você ainda pode usar HTTP 401: stackoverflow.com/questions/928874/…
lanoxx
Sim, basta colocar qualquer coisa no cabeçalho WWW-Authenticate, suponho. Outra resposta semelhante é stackoverflow.com/a/1088127/689161 Ou simplesmente viole a especificação e não se preocupe em enviar o cabeçalho (pelo menos alguns sites fazem isso); 401 ainda é mais apropriado do que 403.
gengkev
Não tenho certeza se "simplesmente colocaria qualquer coisa" no cabeçalho WWW-Authenticate porque não posso ter certeza se a solicitação é tratada pelo meu ajax ou pelo navegador. Além do título desta pergunta, dado o detalhe que sugere autenticação baseada em formulários, eu não enviaria nenhum cabeçalho WWW-Authenticate. Isso ocorre porque não estou pedindo ao navegador para participar do desafio de autenticação / credencial. Eu só quero mostrar um formulário que por acaso é um formulário de logon, mas com algo que o ajax pode usar para identificá-lo é um formulário de logon para que ele possa lidar com isso de forma diferente, como acima.
Swanny
Você deve criar um esquema authn para usar com o cabeçalho. Então o navegador não se envolverá porque não entenderá o esquema. Alguns clientes ficam chateados ou confusos se você não incluir o cabeçalho.
KayEss
-7

Quando a sessão do usuário atinge o tempo limite, eu envio de volta um código de status HTTP 204. Observe que o status HTTP 204 não contém conteúdo. No lado do cliente, eu faço o seguinte:

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

Aqui está a função Reload ():

function Reload() {
    var oForm = document.createElement("form");
    document.body.appendChild(oForm);
    oForm.submit();
    }
Smurfling
fonte
6
Por que você está usando HTTP 204? developer.mozilla.org/en-US/docs/Web/HTTP/Status/204
Will Morgan