Skąd przeglądarka wie, kiedy poprosić użytkownika o zapisanie hasła?


82

Jest to związane z pytaniem, które tutaj zadałem: Jak sprawić, by przeglądarka monitowała o zapisanie hasła?

Oto problem: NIE MOGĘ zmusić przeglądarki, aby monitowała mnie o zapisanie hasła do strony, którą tworzę. (Mówię o pasku, który pojawia się czasami po przesłaniu formularza w przeglądarce Firefox i mówi „Pamiętasz hasło do twoja_witryna.com? Tak / Nie teraz / Nigdy”)

Jest to bardzo frustrujące, ponieważ ta funkcja Firefoksa (i większości innych nowoczesnych przeglądarek, które mam nadzieję działają w podobny sposób) wydaje się być tajemnicą. To jest jak magiczna sztuczka, którą robi przeglądarka, gdzie patrzy na twój kod lub to, co przesyłasz, czy coś, a jeśli "wygląda" jak formularz logowania z polem nazwy użytkownika (lub adresu e-mail) i polem hasła, oferuje zapisać.

Z wyjątkiem tego przypadku, gdy nie oferuje on moim użytkownikom tej opcji po tym, jak skorzystają z mojego formularza logowania, i doprowadza mnie do szału. :-)

(Sprawdziłem ustawienia Firefoksa - NIE powiedziałem przeglądarce „nigdy” dla tej witryny. Powinno pojawić się monit).

Moje pytanie

Jakich heurystyk używa Firefox, aby wiedzieć, kiedy powinien zachęcić użytkownika do zapisania? Nie powinno być trudno odpowiedzieć na to pytanie, ponieważ znajduje się ono w źródle Mozilli (nie wiem, gdzie szukać, bo inaczej spróbuję to wykopać). Nie udało mi się również znaleźć wpisu na blogu lub innej podobnej notatki od programistów Mozilli na ten temat.

(Byłbym w porządku, gdyby odpowiedź na to pytanie dotyczyła Safari lub IE; wyobrażam sobie, że wszystkie przeglądarki używają bardzo podobnych reguł, więc jeśli uda mi się sprawić, by działało w jednej z nich, będzie działać w pozostałych).

(* Pamiętaj, że jeśli Twoja odpowiedź ma coś wspólnego z plikami cookie, szyfrowaniem lub czymkolwiek innym, co dotyczy sposobu przechowywania haseł w mojej lokalnej bazie danych, istnieje duże prawdopodobieństwo, że źle zrozumiałeś moje pytanie. :-)


1
Nie wiem. Czy Twój formularz jest formularzem POST z polem hasła?
zneak

2
Tak, opakowane w tagi <form>, a pola mają nazwy „nazwa użytkownika” i „hasło”. Ładuję go jako osobną warstwę z AJAXem, ale disqus.com też (tylko po to, żeby rzucić tam przykład) i działa dla nich świetnie. Dlatego zamiast (nadal) losowo modyfikować rzeczy, aby zobaczyć, czy to w jakiś sposób pomaga, chcę dowiedzieć się dokładnie, jak myśli przeglądarka.
Eric

Odpowiedzi:


55

Opierając się na tym, co przeczytałem, myślę, że Firefox wykrywa hasła przez form.elements[n].type == "password"(iterując przez wszystkie elementy formularza), a następnie wykrywa pole nazwy użytkownika, przeszukując elementy formularza wstecz w poszukiwaniu pola tekstowego bezpośrednio przed polem hasła (więcej informacji tutaj ). Możesz spróbować czegoś podobnego w Javascript i sprawdzić, czy możesz wykryć pole hasła.

Z tego, co wiem, Twój formularz logowania musi być częścią pliku <form>lub Firefox go nie wykryje. Ustawienie id="password"w polu hasła prawdopodobnie też nie zaszkodzi.

Jeśli nadal sprawia ci to wiele problemów, radziłbym zapytać na jednej z list dyskusyjnych deweloperów projektu Mozilla (możesz nawet otrzymać odpowiedź od programisty, który zaprojektował tę funkcję).


2
To cudowne. Dzięki. Tego właśnie szukam.
Eric

1
Pomogło mi to w uruchomieniu go w przeglądarce Firefox, ale nie mam szczęścia z Chrome. Oto formularz, którego używam: <form id = "myForm" action = "#"> <input id = "username"> <input id = "password" type = "password"> </form>
1,21 gigawata

3
@ 1.21gigawatts- Nie ma „standardowego” sposobu na zrobienie tego (o ile mi wiadomo), więc różne przeglądarki mogą to robić nieco inaczej. Nie wiem, czym różni się proces Chrome od Firefoksa, ale możesz to rozgryźć, przeglądając kod źródłowy Chrome. Jedynym sposobem, w jaki wiedziałem, jak to zrobił, było przeczytanie ich kodu. To jest coś, co ktoś musi udokumentować na dużym wykresie, wymieniając, jak robi to każda przeglądarka ...
bta

3
Autor kodu menedżera hasło poprowadzi Cię przez rzeczy w 2013 blogu - to się opłaca odczytu: blog.mozilla.org/dolske/2013/08/20/on-firefoxs-password-manager
DAT

2
Zaktualizowany link do postów na blogu menedżera haseł: dolske.wordpress.com/2013/08
Vsevolod Golovanov

17

Miałem ten sam problem i znalazłem rozwiązanie:

  1. aby przeglądarka poprosiła o zapisanie hasła, pola nazwy użytkownika i hasła muszą być w formie, a formularz musi zostać faktycznie przesłany. Przycisk przesyłania może zwracać fałsz z modułu obsługi onclick (więc przesłanie w rzeczywistości się nie dzieje).

  2. aby przeglądarka przywróciła wcześniej zapisane hasło, pola wejściowe muszą istnieć w głównym formularzu HTML i nie mogą być tworzone dynamicznie za pomocą javascript. Formularz można utworzyć za pomocą display: none.

Należy pamiętać, że hasło jest wypełniane natychmiast po załadowaniu strony i jest tam obecne przez całą sesję, więc można je odczytać za pomocą wstrzykniętego javascript: znacznie pogarsza takie ataki. Aby tego uniknąć, przekierowanie na osobną stronę tylko po to, aby się zalogować, jest rozsądne i rozwiązuje wszystkie problemy, dla których zacząłeś czytać ten temat :). Częściowo wyczyszczam pola przy wysyłaniu formularza - jeśli użytkownik wyloguje się i chce się ponownie zalogować, to hasło nie jest wpisywane przez przeglądarkę, ale to dla mnie mało istotne.

Viliam



Działa w Firefox 3.5 i IE8, nie działa w Chrome (punkt 1 nie działa). Może zgłoszenie musi być prawdziwe ...
user324356

user324356 - Ustawiłem formularz na „#”, a następnie wywołałem myForm.submit () i to działało w przeglądarce Firefox, ale nie w Chrome, nie jest wyświetlany monit.
1,21 gigawata

1
fyi: Kiedy używasz return falselub event.preventDefault()to nie będzie działać w Chrome z powodu tego błędu: code.google.com/p/chromium/issues/detail?id=282488
mkurz

Jest to zdecydowanie ważne w przypadku obecnego algorytmu używanego przez firefox - nie jest to jedyna rzecz, której szuka menedżer haseł, ale menedżer haseł Firefoksa nie zostanie uruchomiony bez faktycznego przesłania.
DAT

Aktualizacja: Chrome 46 naprawił swoje złe zachowanie - teraz wszystko powinno działać dobrze. Zobacz stackoverflow.com/a/33113374/810109
mkurz

10

Powinieneś spojrzeć na stronę debugowania Mozilla Password Manager i dokumentację nsILoginManager dla autorów rozszerzeń (tylko po podstawowe szczegóły techniczne dotyczące tego, jak Firefox radzi sobie z zarządzaniem hasłami). Możesz tam zagłębić się w odpowiedziach i na innych stronach, do których prowadzą linki, aby dowiedzieć się więcej, niż prawdopodobnie kiedykolwiek chciałeś wiedzieć, jak menedżer haseł współdziała z witrynami i rozszerzeniami.

(W szczególności, jak wskazano w dokumencie debugowania menedżera haseł, upewnij się, że nie masz wyłączonego autouzupełniania w swoim html, ponieważ spowoduje to wyłączenie monitu o zapisanie nazwy użytkownika i hasła)


7

Wydaje się, że działa to w Firefoksie, Chrome i Safari na Macu. Nie testowane w systemie Windows.

<form id="bridgeForm" action="#" target="loginframe" autocomplete="on">
    <input type="text" name="username" id="username" />
    <input type="password" name="password" id="password"/>
</form>

<iframe id="loginframe" name="loginframe" src="anyblankpage.html"></iframe>

Należy to dodać do strony. Nie można go dodać dynamicznie. Formularz i iframe można ustawić na display: none. Jeśli nie ustawisz źródła elementu iframe, zachęta nie pojawi się, dopóki nie prześlesz formularza co najmniej raz.

Następnie wywołaj formularz wyślij ():

bridgeForm.submit();

Czynność może być opcjonalna, a autouzupełnianie może być opcjonalne. Nie testowałem.

Uwaga : w niektórych przeglądarkach formularz musi być uruchomiony na serwerze (nie na serwerze lokalnym ani w systemie plików), zanim przeglądarka odpowie.

Więc to:

http://www.mysite.com/myPage.html

nie to:

http://126.0.0.1/myPage.html
http://localhost/myPage.html
file://directory/myPage.html


@ErikAronesty czy znalazłeś rozwiązanie? Zauważyłem, że w niektórych przeglądarkach (safari) strona musi znajdować się na serwerze, a nie na lokalnym hoście lub systemie plików.
1,21 gigawata,

1
Chrome 46 naprawił swoje niewłaściwe zachowanie - żadne iframeobejścia nie są już potrzebne. Zobacz stackoverflow.com/a/33113374/810109
mkurz

6

U mnie działa z angular, chrome, firefox: (Szukałem i testowałem godzinami - w przypadku Chrome parametr działania formularza ( #) był odpowiedzią. @ 1,21 gigawata , dziękuję !!! Twoja odpowiedź była nieoceniona.)

Formularz

firefox 30.0 - nie potrzebuje ukrytego elementu iframe i przycisku przesyłania (jak pokazano poniżej), ale potrzebuje dyrektywy „login-form-autofill-fix” do rozpoznawania automatycznie wypełnionych poświadczeń, jak poniżej:

<form name="loginForm" login-form-autofill-fix action="#" target="emptyPageForLogin" method="post" ng-submit="login({loginName:grpEmail,password:grpPassword})">
<input type="text" name=username" id="username" ng-model="grpEmail"/>
<input type="password" name="password" id="password" ng-model="grpPassword"/>
<button type="submit">Login</button>
</form>

ukryty element iframe

chrome 35.0 - nie potrzebuje powyższej dyrektywy, ale potrzebuje ukrytego elementu iframe i przycisku przesyłania na prawdziwym formularzu. Jak wygląda ukryty element iframe

<iframe src="emptyPageForLogin.html" id="emptyPageForLogin" name="emptyPageForLogin" style="display:none"></iframe>

dyrektywa angular (przy użyciu jqLite)

Działa to z kątowym 1.2.18

module.directive('loginFormAutofillFix', function() { 
            return function(scope, elem, attrs) {
        if(!attrs.ngSubmit) {
            return;
        }
        setTimeout(function() {
            elem.unbind("submit").bind("submit", function(e) {
                //DO NOT PREVENT!  e.preventDefault(); 
                elem.find("input").triggerHandler("input");
                scope.$apply(attrs.ngSubmit);
            });
        }, 0);
});

poprawka

  • po kilku testach zdałem sobie sprawę, że chrome potrzebuje trochę czasu przy metodzie logowania kątowego (200 ms) - wydaje się, że przekierowanie jest czasami zbyt szybkie dla menedżera haseł.
  • lepsze czyszczenie pamięci przeglądarki ... przy każdej zmianie

od najnowszego chrome pw-manager wypełnia formularz tylko czasami. czasami pojawia się menedżer pw, czasami nie ... teraz wydaje się być funkcją losową.
110 malub

nowy firefox ignoruje automatycznie wypełniane pole hasła. triggerHandler („input”) nie działa. można to rozwiązać za pomocą natywnego zdarzenia (document.createEvent) - rozpal go.
110 malub

1
Chrome 46 naprawił swoje niewłaściwe zachowanie - żadne iframeobejścia nie są już potrzebne. Zobacz stackoverflow.com/a/33113374/810109
mkurz

@ 110maor Zajęło mi dużo czasu zrozumienie twojego postu. Mam nadzieję, że moje zmiany są zgodne z Twoim zamiarem.
jpaugh

3

Cóż, na naszej stronie , pole formularza z nazwą „nazwa użytkownika” wpisz „tekst”, po którym bezpośrednio następuje pole z nazwą „hasło” i wpisz „hasło”, wydaje się działać.


Za szybko dla mnie! Moje myśli dokładnie ... (kasuję odpowiedź)
Ganesh Shankar

Tak. Spróbował tego. Brak szczęścia. :-( Moja teoria jest taka, że ​​mam na stronie coś innego, czego przeglądarka nie lubi / sprawia, że ​​uważa, że ​​strona nie ma formularza logowania ...
Eric


3

Heurystyka jest tutaj dość prosta: wykryj pola o określonych nazwach w określonej kolejności. Które, nie mogę powiedzieć, ale działało dobrze dla mnie w Chrome i IE:

Username field: name "login", type "text";
Password field: name "password", type "password"
Submit button: element "input", type "submit". 
Element "button" type "submit" did not work.

Musiałem zastąpić <button type="submit">przez <input type="submit">uzyskać Dashlane do pracy. Nie mogę uwierzyć, że to nawet coś ...
Bram Verstraten

3

Zauważyłem również, że Chrome nie zaproponuje zapamiętania hasła, jeśli formularz logowania jest nadal obecny po żądaniu logowania, nawet jeśli jest ukryty na stronie.

Myślę, że uważa, że ​​akcja logowania się nie powiodła i dlatego odmawia przechowywania nieprawidłowych danych uwierzytelniających.

Widziany w Chrome 34.0.


1
Chrome 46 naprawił swoje złe zachowanie, ukrywanie formularza po zapytaniu Ajax powinno wystarczyć. Zobacz stackoverflow.com/a/33113374/810109
mkurz


0

Poza tym, co już zostało powiedziane, zdałem sobie sprawę, że pola wejściowe nie mogą być „wyłączane”. Mieliśmy wieloetapowe logowanie, które najpierw pyta o nazwę użytkownika, a następnie na następnym ekranie o hasło. Na tym drugim ekranie powtórzyliśmy e-mail, ale wyłączyliśmy go, co uniemożliwiło Chrome et. glin. z rozpoznania jako prawidłowego pola dla nazwy użytkownika.

Ponieważ naprawdę chcieliśmy zachować to wyłączone pole wejściowe, skończyło się na tym hackerskim obejściu:

<input type="text" name="display-username" id="display-username" value="ENTERED_USERNAME" placeholder="Username" disabled="disabled">
<input type="text" name="username" id="username" value="ENTERED_USERNAME" placeholder="Username" style="display: none;">
<input type="password" name="password" id="password" value="" autofocus="autofocus" autocomplete="on" placeholder="Password" required="required">

Nie posunąłbym się tak daleko, aby to polecić, ale może wskazuje to komuś na coś w ich własnym kodzie:

  1. Pierwszy element wyświetla nazwę użytkownika w wyłączonym polu wejściowym. Wyłączone nie jest przesyłane jako część formularza, a wyłączone nie jest rozpoznawane przez przeglądarkę.
  2. Drugi element to prawidłowe pole wejściowe, z typem = "tekst" i nazwą / id = "nazwa użytkownika". Jest to rozpoznawane przez przeglądarkę. Aby uniemożliwić użytkownikowi jego edycję, ukrywamy go za pomocą CSS (display: none).

W sytuacjach, gdy potrzebujesz danych wejściowych, których wartość została przesłana, ale których użytkownik nie może zmienić, możesz spróbować „tylko do odczytu” zamiast „wyłączone”.
David Brown

0

Jeśli masz na przykład dwa type = text w swoim formularzu przed wejściem type = password, przeglądarka wykryje najbliższy typ wejścia type = text dla Twojej nazwy użytkownika.

Nie ma znaczenia, że ​​inne dane wejściowe to = nazwa użytkownika i nazwa = nazwa użytkownika

Aby rozwiązać ten problem, musisz umieścić swoją nazwę użytkownika, którą chcesz zapisać, dokładnie przed wprowadzonym hasłem

Powodzenia :-)


-2

Główne słowo kluczowe jest tutaj,

   <input type="password">

1
Spróbuj wyjaśnić swoją odpowiedź, podając więcej szczegółów, ponieważ będzie to pomocne dla innych.
Ashish Duklan,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.