É possível desconectar o usuário de um site se ele estiver usando autenticação básica?
A sessão de assassinato não é suficiente, pois, uma vez que o usuário é autenticado, cada solicitação contém informações de login, para que o usuário seja automaticamente conectado na próxima vez em que acessar o site usando as mesmas credenciais.
Até agora, a única solução é fechar o navegador, mas isso não é aceitável do ponto de vista da usabilidade.
/
página, eles serão automaticamente conectados novamente.Respostas:
A autenticação básica não foi projetada para gerenciar o logoff. Você pode fazer isso, mas não completamente automaticamente.
O que você precisa fazer é fazer com que o usuário clique em um link de logout e envie um '401 Não Autorizado' em resposta, usando o mesmo domínio e no mesmo nível de pasta de URL que o 401 normal que você envia solicitando um logon.
Eles devem ser direcionados para inserir credenciais erradas a seguir, por exemplo. um nome de usuário e senha em branco e, em resposta, você envia uma página "Você efetuou logout com êxito". As credenciais incorretas / em branco substituirão as credenciais corretas anteriores.
Em resumo, o script de logout inverte a lógica do script de logon, retornando apenas a página de sucesso se o usuário não estiver passando as credenciais corretas.
A questão é se a caixa de senha um tanto curiosa “não digite sua senha” atenderá à aceitação do usuário. Os gerenciadores de senhas que tentam preencher automaticamente a senha também podem atrapalhar aqui.
Edite para adicionar em resposta ao comentário: o novo login é um problema ligeiramente diferente (a menos que você precise de um logout / login em duas etapas, obviamente). Você deve rejeitar (401) a primeira tentativa de acessar o link de logon novamente, depois aceitar a segunda (que provavelmente possui um nome de usuário / senha diferente). Existem algumas maneiras de fazer isso. Um seria incluir o nome de usuário atual no link de logout (por exemplo, / relogin? Nome de usuário) e rejeitar quando as credenciais corresponderem ao nome de usuário.
fonte
Uma adição à resposta de bobince ...
Com o Ajax, você pode ter o link / botão 'Logout' conectado a uma função Javascript. Faça com que essa função envie o XMLHttpRequest com um nome de usuário e senha incorretos. Isso deve retornar a 401. Em seguida, defina document.location de volta à página de pré-login. Dessa forma, o usuário nunca verá a caixa de diálogo de logon extra durante o logout, nem precisará se lembrar de colocar más credenciais.
fonte
Peça ao usuário que clique em um link para https: // log: [email protected]/ . Isso substituirá as credenciais existentes por credenciais inválidas; desconectando-os.
fonte
Você pode fazer isso inteiramente em JavaScript:
O IE possui (por muito tempo) a API padrão para limpar o cache de autenticação básica:
Deve retornar true quando funciona. Retorna falso, indefinido ou explode em outros navegadores.
Novos navegadores (em dezembro de 2012: Chrome, FireFox, Safari) têm um comportamento "mágico". Se eles virem uma solicitação de autenticação básica bem - sucedida com qualquer outro nome de usuário falso (digamos
logout
), eles limparão o cache de credenciais e possivelmente o definirão para esse novo nome de usuário falso, que você precisa garantir que não seja um nome de usuário válido para exibir o conteúdo.Exemplo básico disso é:
Uma maneira "assíncrona" de fazer o acima é fazer uma chamada AJAX utilizando o
logout
nome de usuário. Exemplo:Você também pode torná-lo um bookmarklet:
javascript:(function(c){var a,b="You should be logged out now.";try{a=document.execCommand("ClearAuthenticationCache")}catch(d){}a||((a=window.XMLHttpRequest?new window.XMLHttpRequest:window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):void 0)?(a.open("HEAD",c||location.href,!0,"logout",(new Date).getTime().toString()),a.send(""),a=1):a=void 0);a||(b="Your browser is too old or too weird to support log out functionality. Close all windows and restart the browser.");alert(b)})(/*pass safeLocation here if you need*/);
fonte
logout
e / ou URL de logout do lado do servidor ?logout
existir e possuir a senha gerada. Nesse caso quase impossivelmente raro, altere o ID do usuário para um que não exista no seu sistema.<a href='javascript:......need*/);'>Logout</a>
A função a seguir está confirmada para o Firefox 40, Chrome 44, Opera 31 e IE 11. O
Bowser é usado para detecção do navegador, o jQuery também é usado.
- secUrl é o URL de uma área protegida por senha da qual efetuar logout.
- redirUrl é o URL para uma área não protegida por senha (página de sucesso do logout).
- você pode querer aumentar o temporizador de redirecionamento (atualmente 200ms).
fonte
$.ajax
variante ser síncrona (async: false
) eaxmlhttp
variante sendo assíncrona (otrue
noopen()
)?(bowser.gecko)
para(bowser.gecko || bowser.blink)
.$.ajax
e o webkit usanew XMLHttpRequest
? O gecko / blink não deveria poder fazerXMLHttpRequest
e o webkit$.ajax
também? Estou confuso.Aqui está um exemplo muito simples de Javascript usando jQuery:
Este usuário efetua logout sem mostrar a caixa de logon do navegador novamente e depois o redireciona para uma página desconectada
fonte
Isso não é diretamente possível com a autenticação básica.
Não há mecanismo na especificação HTTP para o servidor informar ao navegador para parar de enviar as credenciais que o usuário já apresentou.
Existem "hacks" (consulte outras respostas) normalmente envolvendo o uso de XMLHttpRequest para enviar uma solicitação HTTP com credenciais incorretas para substituir as fornecidas originalmente.
fonte
Isso está funcionando para o IE / Netscape / Chrome:
fonte
Na verdade, é bem simples.
Basta visitar o seguinte no seu navegador e usar credenciais incorretas: http: // nome do usuário: [email protected]
Isso deve "desconectar você".
fonte
Tudo o que você precisa é redirecionar o usuário em algum URL de logout e retornar
401 Unauthorized
erro nele. Na página de erro (que deve ser acessível sem autenticação básica), você precisa fornecer um link completo para sua página inicial (incluindo esquema e nome do host). O usuário clicará neste link e o navegador solicitará credenciais novamente.Exemplo para Nginx:
Página de erro
/home/user/errors/401.html
:fonte
http_host
em401.html
vez de, simplesmentehost
, como o primeiro também adiciona o número da porta (no caso de uma porta não-padrão está a ser usado)fonte
fonte
Com base no que li acima, recebi uma solução simples que funciona em qualquer navegador:
1) na página de logout, você chama um ajax para o back-end de login. Seu back-end de login deve aceitar usuário de logout. Depois que o back-end aceita, o navegador limpa o usuário atual e assume o usuário "logout".
2) Agora, quando o usuário voltar ao arquivo de índice normal, ele tentará entrar automaticamente no sistema com o usuário "logout". Nesta segunda vez, você deve bloqueá-lo, respondendo com 401 para chamar a caixa de diálogo de login / senha.
3) Existem várias maneiras de fazer isso: criei dois back-ends de login, um que aceita o usuário de logout e outro que não. Minha página de login normal usa a que não aceita, minha página de logout usa a que aceita.
fonte
Acabei de testar o seguinte no Chrome (79), Firefox (71) e Edge (44) e funciona bem. Aplica a solução de script como outros observados acima.
Basta adicionar um link "Logout" e, quando clicar, retornar o seguinte html
fonte
Este JavaScript deve estar funcionando para todos os navegadores da versão mais recente:
fonte
adicione isso ao seu aplicativo:
fonte
digite
chrome://restart
na barra de endereço e o chrome, com todos os aplicativos em execução em segundo plano, será reiniciado e o cache de senha de autenticação será limpo.fonte
Apenas para o registro, existe um novo cabeçalho de resposta HTTP chamado
Clear-Site-Data
. Se a resposta do servidor incluir umClear-Site-Data: "cookies"
cabeçalho, as credenciais de autenticação (não apenas os cookies) deverão ser removidas. Eu testei no Chrome 77, mas este aviso aparece no console:E as credenciais de autenticação não são removidas, portanto isso não funciona (por enquanto) para implementar logins de autenticação básicos, mas talvez no futuro o faça. Não testou em outros navegadores.
Referências:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data
https://www.w3.org/TR/clear-site-data/
https://github.com/w3c/webappsec-clear-site-data
https://caniuse.com/#feat=mdn-http_headers_clear-site-data_cookies
fonte
O envio
https://invalid_login@hostname
funciona bem em qualquer lugar, exceto no Safari no Mac (bem, o Edge não foi verificado, mas deve funcionar lá também).O logout não funciona no Safari quando um usuário seleciona 'lembrar senha' no pop-up Autenticação básica HTTP. Nesse caso, a senha é armazenada em Acesso ao chaveiro (Finder> Aplicativos> Utilitários> Acesso ao chaveiro (ou CMD + SPACE e digite "Acesso ao chaveiro")). Enviando
https://invalid_login@hostname
não afeta o acesso ao chaveiro; portanto, com esta caixa de seleção, não é possível fazer logout no Safari no Mac. Pelo menos é assim que funciona para mim.MacOS Mojave (10.14.6), Safari 12.1.2.
O código abaixo funciona bem para mim no Firefox (73), Chrome (80) e Safari (12). Quando um usuário navega para uma página de logout, o código é executado e descarta as credenciais.
Por algum motivo, o Safari não salva credenciais no pop-up Autenticação básica HTTP, mesmo quando a opção 'lembrar senha' está selecionada. Os outros navegadores fazem isso corretamente.
fonte
fonte
Atualizei a solução do mthoring para versões modernas do Chrome:
fonte