Como posso obter o navegador para solicitar a senha?

Ei, estou trabalhando em um aplicativo da web que tem uma checkbox de diálogo de login que funciona assim:

  1. Usuário clica em “login”
  2. Formulário de login HTML é carregado com AJAX e exibido no DIV na página
  3. O usuário insere campos de usuário / aprovação e clica em enviar. NÃO é um – user / pass é enviado via AJAX
  4. Se o usuário / passe estiver correto, a página é recarregada com o usuário logado.
  5. Se user / pass for ruim, a página NÃO será recarregada, mas a mensagem de erro será exibida no DIV e o usuário tentará novamente.

Aqui está o problema: o navegador nunca oferece o prompt usual “Salvar esta senha? Sim / Nunca / Não Agora” que é feito para outros sites.

Eu tentei envolver as tags

em com “autocomplete = ‘on'”, mas isso não fez diferença.

É possível obter o navegador para oferecer para armazenar a senha sem um grande retrabalho do meu stream de login?

obrigado Eric

ps para adicionar à minha pergunta, eu definitivamente estou trabalhando com browers que armazenam senhas, e eu nunca cliquei em “nunca para este site” … este é um problema técnico com o navegador não detectando que é um formulário de login, não erro do operador 🙂

Eu encontrei uma solução completa para esta questão. (Eu testei isso no Chrome 27 e no Firefox 21).

Existem duas coisas para saber:

  1. Trigger ‘Salvar senha’ e
  2. Restaurar o nome de usuário / senha salvos

1. Trigger ‘Salvar senha’:

Para o Firefox 21 , ‘Salvar senha’ é acionado quando detecta que há um formulário contendo o campo de texto de input e o campo de senha de input é enviado. Então nós só precisamos usar

 $('#loginButton').click(someFunctionForLogin); $('#loginForm').submit(function(event){event.preventDefault();}); 

someFunctionForLogin() faz o logon ajax e recarrega / redireciona para a página event.preventDefault() enquanto event.preventDefault() bloqueia o redirecionamento original devido ao envio do formulário.

Se você lida apenas com o Firefox, a solução acima é suficiente, mas não funciona no Chrome 27. Em seguida, você perguntará como acionar “Salvar senha” no Chrome 27.

Para o Chrome 27 , “Salvar senha” é acionado após ser redirecionado para a página, enviando o formulário que contém o campo de texto de input com o atributo name = ‘username’ e o campo de senha de input com o atributo name = ‘password’ . Portanto, não podemos bloquear o redirecionamento devido ao envio do formulário, mas podemos fazer o redirecionamento após o login do ajax. (Se você quiser que o login ajax não recarregue a página ou não redirecione para uma página, infelizmente, minha solução não funciona.) Então, nós podemos usar

 

Botão com type = ‘button’ fará com que o formulário não seja enviado quando o botão for clicado. Em seguida, vincule uma function ao botão para o login ajax. Finalmente, chamando $('#loginForm').submit(); redireciona para a página conectada. Se a página conectada for a página atual, você poderá replace ‘signedIn.xxx’ pela página atual para fazer a ‘atualização’.

Agora, você descobrirá que o método para o Chrome 27 também funciona no Firefox 21. Portanto, é melhor usá-lo.

2. Restaure o nome de usuário / senha salvos:

Se você já tiver o loginForm codificado como HTML, não encontrará nenhum problema para restaurar a senha salva no loginForm.
No entanto, o nome de usuário / senha salvos não será vinculado ao loginForm se você usar js / jquery para criar o loginForm dinamicamente, porque o nome de usuário / senha salvos só é vinculado quando o documento é carregado.
Portanto, você precisava codificar o loginForm como HTML e usar js / jquery para mover / mostrar / ocultar o loginForm dinamicamente.


Observação: Se você fizer o login do ajax, não adicione autocomplete='off' no formulário de tag como

 

autocomplete='off' fará com que o nome de usuário / senha de restauração no loginForm falhe porque você não permite que ele ‘autocomplete’ o nome de usuário / senha.

Usando um botão para entrar:

Se você usar um type="button" com um manipulador onclick para efetuar login usando ajax , o navegador não oferecerá para salvar a senha.

 

Como esse formulário não possui um botão de envio e não possui nenhum campo de ação, o navegador não oferecerá para salvar a senha.


Usando um botão de envio para entrar:

No entanto, se você alterar o botão para type="submit" e manipular o envio, o navegador oferecerá para salvar a senha.

 

Usando esse método, o navegador deve oferecer para salvar a senha.


Aqui está o Javascript usado nos dois methods:

 function login(f){ var username = f.username.value; var password = f.password.value; /* Make your validation and ajax magic here. */ return false; //or the form will post your data to login.php } 

Eu mesmo tenho lutado com isso e finalmente consegui rastrear o problema e o que estava causando falhas.

Tudo resultou do fato de que meu formulário de login estava sendo injetado dinamicamente na página (usando o backbone.js). Assim que eu inseri meu formulário de login diretamente no meu arquivo index.html, tudo funcionou como um encanto.

Acho que isso acontece porque o navegador precisa estar ciente de que existe um formulário de login, mas como o meu estava sendo injetado dinamicamente na página, ele não sabia que existia um formulário de login “real”.

Esta solução funcionou para mim postado por Eric nos fóruns de codificação


A razão pela qual isso não é solicitado é porque o navegador precisa da página para atualizar fisicamente para o servidor. Um pequeno truque que você pode fazer é executar duas ações com o formulário. A primeira ação é o onsubmit, chame seu código Ajax. Além disso, o formulário segmenta um iframe oculto.

Código:

  

Veja se isso faz com que o prompt apareça.

Eric


Postado em http://www.codingforums.com/showthread.php?t=123007

Há uma solução definitiva para forçar todos os navegadores (testados: chrome 25, safari 5.1, IE10, Firefox 16) a solicitar a salvaguarda da senha usando o jQuery e o pedido ajax :

JS:

 $(document).ready(function() { $('form').bind('submit', $('form'), function(event) { var form = this; event.preventDefault(); event.stopPropagation(); if (form.submitted) { return; } form.submitted = true; $.ajax({ url: '/login/api/jsonrpc/', data: { username: $('input[name=username]').val(), password: $('input[name=password]').val() }, success: function(response) { form.submitted = false; form.submit(); //invoke the save password in browser } }); }); }); 

HTML:

 

O truque está em parar o formulário para enviar seu próprio caminho (event.stopPropagation ()), em vez de enviar seu próprio código ($ .ajax ()) e no callback de sucesso do ajax enviar o formulário novamente para que o navegador o capture e exiba o pedido para salvar a senha. Você também pode adicionar algum manipulador de erros, etc.

Espero que tenha ajudado alguém.

Eu tentei a resposta do spetson, mas isso não funcionou para mim no Chrome 18. O que funcionou foi adicionar um manipulador de carga ao iframe e não interromper o envio (jQuery 1.7):

 function getSessions() { $.getJSON("sessions", function (data, textStatus) { // Do stuff }).error(function () { $('#loginForm').fadeIn(); }); } $('form', '#loginForm').submit(function (e) { $('#loginForm').fadeOut(); }); $('#loginframe').on('load', getSessions); getSessions(); 

O HTML:

 

Please log in


getSessions () faz uma chamada AJAX e mostra o loginForm div se falhar. (O serviço da web retornará 403 se o usuário não estiver autenticado).

Testado para trabalhar em FF e IE8 também.

O navegador pode não conseguir detectar que seu formulário é um formulário de login. De acordo com algumas das discussões desta questão anterior , um navegador procura campos de formulário que se parecem com . O seu campo de formulário de senha foi implementado de maneira semelhante?

Edit: Para responder às suas perguntas abaixo, acho que o Firefox detecta senhas por form.elements[n].type == "password" (iterando todos os elementos do formulário) e, em seguida, detecta o campo username pesquisando para trás através de elementos de formulário para o campo de texto imediatamente antes do campo de senha (mais informações aqui ). Pelo que posso dizer, o seu formulário de login precisa ser parte de um

ou o Firefox não o detectará.

Passei muito tempo lendo as várias respostas neste tópico e, para mim, era algo realmente diferente (relacionado, mas diferente). No Mobile Safari (dispositivos iOS), se o formulário de login estiver HIDDEN quando a página for carregada, o prompt não será exibido (depois que você mostrar o formulário, envie-o). Você pode testar com o seguinte código, que exibe o formulário 5 segundos após o carregamento da página. Remova o JS e o display: none e ele funciona. Eu ainda estou para encontrar uma solução para isso, apenas postado no caso de alguém ter o mesmo problema e não pode descobrir a causa.

JS:

 $(function() { setTimeout(function() { $('form').fadeIn(); }, 5000); }); 

HTML:

 

O código a seguir é testado em

  • Chrome 39.0.2171.99m: TRABALHO
  • Android Chrome 39.0.2171.93: TRABALHO
  • Navegador Android (Android 4.4): NÃO TRABALHANDO
  • Internet Explorer 5+ (emulado): WORKING
  • Internet Explorer 11.0.9600.17498 / Update-Version: 11.0.15: TRABALHO
  • Firefox 35.0: TRABALHANDO

JS-Fiddle:
http://jsfiddle.net/ocozggqu/

Post-code:

 // modified post-code from https://stackoverflow.com/questions/133925/javascript-post-request-like-a-form-submit function post(path, params, method) { method = method || "post"; // Set method to post by default if not specified. // The rest of this code assumes you are not using a library. // It can be made less wordy if you use one. var form = document.createElement("form"); form.id = "dynamicform" + Math.random(); form.setAttribute("method", method); form.setAttribute("action", path); form.setAttribute("style", "display: none"); // Internet Explorer needs this form.setAttribute("onsubmit", "window.external.AutoCompleteSaveForm(document.getElementById('" + form.id + "'))"); for (var key in params) { if (params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); // Internet Explorer needs a "password"-field to show the store-password-dialog hiddenField.setAttribute("type", key == "password" ? "password" : "text"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); form.appendChild(hiddenField); } } var submitButton = document.createElement("input"); submitButton.setAttribute("type", "submit"); form.appendChild(submitButton); document.body.appendChild(form); //form.submit(); does not work on Internet Explorer submitButton.click(); // "click" on submit-button needed for Internet Explorer } 

Observações

  • Para formulários de login dynamics, é necessária uma chamada para window.external.AutoCompleteSaveForm
  • O Internet Explorer precisa de um campo “senha” para mostrar a checkbox de diálogo armazenar senha
  • O Internet Explorer parece exigir um clique no botão enviar (mesmo que seja um clique falso)

Aqui está um exemplo de código de login do ajax:

 function login(username, password, remember, redirectUrl) { // "account/login" sets a cookie if successful return $.postJSON("account/login", { username: username, password: password, remember: remember, returnUrl: redirectUrl }) .done(function () { // login succeeded, issue a manual page-redirect to show the store-password-dialog post( redirectUrl, { username: username, password: password, remember: remember, returnUrl: redirectUrl }, "post"); }) .fail(function () { // show error }); }; 

Observações

  • “conta / login” define um cookie se for bem sucedido
  • Redirecionamento de página (“manualmente” iniciado por js-code) parece ser necessário. Eu também testei um post de iframe, mas não obtive sucesso com isso.

Eu encontrei uma solução bastante elegante (ou hack, o que se encheckbox) para os usuários Prototype.JS, sendo um dos últimos holdouts usando Prototype. Uma simples substituição dos methods jQuery correspondentes deve fazer o truque.

Primeiro, verifique se há uma tag

e um botão de envio com um nome de class que possa ser mencionado posteriormente (neste caso faux-submit ) que esteja nested em um elemento com um conjunto de estilos display:none , conforme ilustrado abaixo :

 

Em seguida, crie um observador de cliques para o button , que “enviará” o formulário conforme ilustrado:

 $('submit_button').observe('click', function(event) { $('login_form').submit(); }); 

Em seguida, crie um ouvinte para submit evento e pare-o. event.stop() interromperá todos os events de envio no DOM, a menos que esteja em Event.findElement com a class do botão de input oculto (como acima, faux-submit ):

 document.observe('submit', function(event) { if (event.findElement(".faux-submit")) { event.stop(); } }); 

Isso é testado como trabalhando no Firefox 43 e no Chrome 50.

Seu site provavelmente já está na lista em que o navegador é avisado para não solicitar uma senha. No firefox, Opções -> Segurança -> Lembrar senha para sites [checkbox de seleção] – exceções [botão]

adicione um pouco mais de informação à resposta do @Michal Roharik.

Se sua chamada ajax retornará um URL de retorno, você deve usar jquery para alterar o atributo action do formulário para esse URL antes de chamar form.submit

ex.

 $(form).attr('action', ReturnPath); form.submitted = false; form.submit(); 

Eu tive problema semelhante, o login foi feito com ajax, mas os navegadores (firefox, chrome, safari e IE 7-10) não ofereceriam para salvar senhas se o formulário (#loginForm) fosse enviado com ajax.

Como SOLUÇÃO , adicionei a input de envio oculta (#loginFormHiddenSubmit) para o formulário que foi enviado por ajax e, após a chamada ajax retornar o sucesso, acionaria um clique para input de envio oculta. A página de qualquer maneira necessária para ser atualizada. O clique pode ser acionado com:

 jQuery('#loginFormHiddenSubmit').click(); 

O motivo pelo qual eu adicionei o botão de envio oculto é porque:

 jQuery('#loginForm').submit(); 

não ofereceria para salvar senha no IE (embora tenha funcionado em outros navegadores).

Nem todo navegador (por exemplo, o IE 6) tem opções para lembrar credenciais.

Uma coisa que você pode fazer é (uma vez que o usuário efetue login com sucesso) armazenar as informações do usuário por meio do cookie e ter uma opção “Lembrar-se desta máquina”. Dessa forma, quando o usuário acessa novamente (mesmo que esteja desconectado), seu aplicativo da Web pode recuperar o cookie e obter as informações do usuário (ID do usuário + ID da session) e permitir que ele continue trabalhando.

Espero que isso possa ser sugestivo. 🙂

A verdade é que você não pode forçar o navegador a perguntar. Tenho certeza que o navegador tem seu próprio algoritmo para adivinhar se você digitou um nome de usuário / senha, como procurar por uma input de type="password" mas você não pode definir nada para forçar o navegador.

Você poderia, como outros sugerem, adicionar informações do usuário em um cookie. Se você fizer isso, é melhor criptografá-lo e não armazenar sua senha. Talvez armazene seu nome de usuário no máximo.

Você pode append a checkbox de diálogo ao formulário, portanto, todas essas inputs estão em um formulário. A outra coisa é tornar o campo de texto da senha logo após o campo de texto do nome de usuário.

Este trabalho é muito melhor para mim, porque é 100% Ajax e o navegador detecta o login.

 
Login

Usar um cookie provavelmente seria a melhor maneira de fazer isso.

Você poderia ter uma checkbox de seleção para “Lembrar de mim?” e faça com que o formulário crie um cookie para armazenar o // login do usuário // info. EDIT: informações da session do usuário

Para criar um cookie, você precisará processar o formulário de login com o PHP.