Як браузер знає, коли запропонувати користувачеві зберегти пароль?


82

Це пов’язано з питанням, яке я задав тут: Як я можу отримати браузер із запитом зберегти пароль?

У цьому проблема: Я НЕ МОГУ отримати браузер, який запропонує мені зберегти пароль для веб-сайту, який я розробляю. .

Це надзвичайно розчаровує, оскільки ця особливість Firefox (і більшості інших сучасних браузерів, які, я сподіваюсь, працюють подібним чином), здається, є загадкою. Це як чарівний трюк, який робить браузер, де він переглядає ваш код, або те, що ви подаєте, або щось інше, і якщо це "виглядає" як форма для входу з полем імені користувача (або адреси електронної пошти) та поля пароля, він пропонує зберегти.

За винятком цього випадку, коли це не пропонує моїм користувачам таку можливість після використання моєї форми входу, і це збиває мене з розуму. :-)

(Я перевірив свої налаштування Firefox - я НЕ сказав браузеру "ніколи" для цього сайту. Це повинно бути підказкою.)

Моє запитання

Які евристики використовує Firefox, щоб знати, коли він повинен запропонувати користувачеві зберегти? Відповісти на це не повинно бути надто складно, оскільки це саме там, у джерелі Mozilla (я не знаю, де шукати, інакше я спробував би сам це розкопати). Мені також не пощастило знайти допис у блозі чи якусь іншу подібну записку розробника про це від розробників Mozilla.

(Мені було б добре, якщо б на це запитання відповіли для Safari або IE; я уявляю, що всі браузери користуються дуже схожими правилами, тому, якщо я зможу змусити його працювати в одному з них, це буде працювати в інших.)

(* Зверніть увагу, що якщо ваша відповідь мені пов’язана з файлами cookie, шифруванням чи будь-чим іншим, що стосується того, як я зберігаю паролі в своїй локальній базі даних, то шанси на те, що ви неправильно зрозуміли моє запитання. :-)


1
Я не знаю. Ваша форма - це форма POST із полем пароля?
zneak

2
Так, загорнуті в теги <form>, а поля мають імена «ім’я користувача» та «пароль». Я завантажую його як окремий шар за допомогою AJAX, але це робить і disqus.com (просто для того, щоб викинути приклад), і це чудово для них працює. Ось чому, замість того, щоб (продовжувати) довільно налаштовувати речі, щоб побачити, чи це якось допомагає, я хочу з’ясувати, як саме мислить браузер.
Ерік

Відповіді:


55

На основі прочитаного я вважаю, що Firefox виявляє паролі form.elements[n].type == "password"(перебираючи всі елементи форми), а потім виявляє поле імені користувача, здійснюючи пошук в елементах форми для текстового поля безпосередньо перед полем пароля (докладніше тут ). Ви можете спробувати щось подібне в Javascript і перевірити, чи зможете ви виявити поле вашого пароля.

З того, що я можу сказати, ваша форма входу повинна бути частиною <form>або Firefox її не виявить. Налаштування id="password"в полі пароля, ймовірно, також не може зашкодити.

Якщо це все одно доставляє вам багато проблем, я б порадив звернутися до одного зі списків розсилки розробників проекту Mozilla (можливо, ви навіть отримаєте відповідь від розробника, який розробив цю функцію).


2
Це дивовижно. Дякую. Це те, що я шукаю.
Ерік

1
Це допомогло мені змусити його працювати у Firefox, але мені не пощастило з Chrome. Це я використовую форму: <form id = "myForm" action = "#"> <input id = "username"> <input id = "password" type = "password"> </form>
1,21 гігават

3
@ 1.21gigawatts - Не існує "стандартного" способу зробити це (наскільки мені відомо), тому різні браузери можуть робити це дещо інакше. Я не знаю, чим процес Chrome відрізняється від Firefox, але, можливо, ви зможете це зрозуміти, якщо переглянете вихідний код Chrome. Я знав, як це зробив Firefox, лише читаючи їх код. Це те, що комусь потрібно задокументувати у великій діаграмі, перелічивши, як це робить кожен браузер ...
bta

3
Автор коду менеджера паролів проведе вас через речі в 2013 блозі - це варто читати: blog.mozilla.org/dolske/2013/08/20/on-firefoxs-password-manager
Дати

2
Оновлене посилання на повідомлення блогу менеджера паролів: dolske.wordpress.com/2013/08
Всеволод Голованов

17

У мене була та ж проблема і я знайшов рішення:

  1. щоб браузер попросив зберегти пароль, ім'я користувача та поля для введення пароля повинні бути у формі, і ця форма повинна бути фактично подана. Кнопка надіслати може повернути false з обробника onclick (тому подання насправді не відбувається).

  2. щоб браузер відновив раніше збережений пароль, поля введення повинні існувати у головній формі HTML і не створюватися за допомогою javascript динамічно. Форму можна створити за допомогою display: none.

Слід зазначити, що пароль заповнюється відразу після завантаження сторінки і присутній там протягом усього сеансу, тому його можна прочитати за допомогою введеного javascript: це значно погіршує такі атаки. Щоб цього уникнути, переадресація на окрему сторінку лише для входу є розумною, і вона вирішує всі проблеми, щодо яких ви почали читати цю тему :). Як часткове рішення я очищаю поля після надсилання форми - якщо користувач виходить із системи та хоче ввійти ще раз, браузер не заповнює пароль, але це для мене незначно.

Віліам



Працює у Firefox 3.5 та IE8, не працює у Chrome (пункт 1 не працює). Можливо, подання має бути справжнім ...
user324356

user324356 - Я встановив для форми форму "#", яку потім назвав myForm.submit (), і яка працювала у Firefox, але не Chrome не підказує.
1,21 гігават

1
fyi: Коли ви використовуєте return falseабо event.preventDefault()це не буде працювати в Chrome через цю помилку: code.google.com/p/chromium/issues/detail?id=282488
mkurz

Це, безумовно, важливо для поточного алгоритму, що використовується firefox - це не єдине, що "шукає" менеджер паролів, але менеджер паролів firefox не буде запускатися без фактичного надсилання.
Дати

Оновлення: Chrome 46 виправив неправильну поведінку - зараз все повинно працювати нормально. Див stackoverflow.com/a/33113374/810109
mkurz

10

Ви повинні переглянути сторінку налагодження Mozilla Password Manager та документи nsILoginManager для авторів розширень (лише для дрібних технічних деталей того, як Firefox має справу з управління паролями). Ви можете заглибитися у відповіді там та інші сторінки, на які там пов’язано, щоб дізнатися більше, ніж ви, мабуть, хотіли знати, як менеджер паролів взаємодіє з веб-сайтами та розширеннями.

(Зокрема, як зазначено в документі налагодження диспетчера паролів, переконайтесь, що у вашому html не вимкнено автозаповнення, оскільки це буде пригнічувати запит на збереження імені користувача та пароля)


7

Здається, це працює для Firefox, Chrome та Safari на Mac. Не перевірено на 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>

Це потрібно додати на сторінку. Його не можна додавати динамічно. Форму та iframe можна встановити для відображення: немає. Якщо ви не встановите src iframe, підказка не відображатиметься, доки ви не принаймні один раз надішлете форму.

Потім зателефонуйте у форму submit ():

bridgeForm.submit();

Дія може бути необов’язковою, а автозаповнення необов’язковою. Не тестував.

Примітка : У деяких браузерах форма повинна працювати на сервері (не на localhost і не у файловій системі), перш ніж браузер відповість.

Отже це:

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

не це:

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


@ErikAronesty Ви придумали рішення? Я помітив, що в деяких браузерах (сафарі) сторінка повинна бути на сервері, а не на локальному хості чи у файловій системі.
1,21 гігават

1
Chrome 46 виправив свою неправильну поведінку - iframeобхідних шляхів більше не потрібно. Див stackoverflow.com/a/33113374/810109
mkurz

6

Працює у мене з angular, chrome, firefox: (я шукав і тестував годинами - на хром відповідав параметр дії форми ( #). @ 1,21 гігават , дякую !!! Ваша відповідь була неоціненною.)

форму

firefox 30.0 - не потребує прихованої iframe та кнопки подання (як показано нижче), але потрібна директива "login-form-autofill-fix" для розпізнавання автозаповнення кредендалів, як показано нижче:

<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>

прихований iframe

chrome 35.0 - не потрібна вищевказана директива, але потрібна прихована рамка та кнопка подання у реальній формі. Прихований iframe виглядає так

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

директива кута (за допомогою jqLite)

Це працює з кутовим 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);
});

поправка

  • після певного тестування я зрозумів, що chrome потребує невеликого тайм-ауту методом кутового входу (200 мс) - схоже, перенаправлення іноді буває занадто швидким для менеджера паролів.
  • краще очистити кеш браузера ... з кожною зміною

оскільки найновіший хром, pw-менеджер заповнює форму лише іноді. також менеджер pw іноді спливає, іноді ні ... здається, це рандомізована функція зараз.
110маор

новий Firefox ігнорує поле автоматичного заповнення пароля. triggerHandler ("input") не працює. це можна вирішити за допомогою власної події (document.createEvent) - надіслати це пожежею.
110маор

1
Chrome 46 виправив свою неправильну поведінку - iframeобхідних шляхів більше не потрібно. Див stackoverflow.com/a/33113374/810109
mkurz

@ 110maor Мені знадобилось багато часу, щоб зрозуміти твій пост. Сподіваюся, мої редагування відповідають вашим намірам.
jpaugh

3

Що ж, на нашому сайті поле форми з ім’ям «ім’я користувача» введіть «текст», за яким слідує поле з ім’ям «пароль» і «пароль», здається, робить трюк.


Надто швидко для мене! Мої думки точно ... (Я видаляю свою відповідь)
Ганеш Шанкар

Так. Спробував. Нещастить. :-( Моя теорія полягає в тому, що у мене є дещо - що ще на сторінці , що браузер не любить / робить думаю , що сторінка не має форму входу ...
Ерік

3

Якщо ви використовуєте логін AJAX, подивіться на цей вихідний код: https://gist.github.com/968927

Він полягає у поданні форми входу у приховану рамку, щоб IE та Chrome могли виявити фактичний вхід без необхідності перезавантажувати сторінку.


Chrome 46 виправив свою неправильну поведінку - iframeобхідних шляхів більше не потрібно. Див stackoverflow.com/a/33113374/810109
mkurz

3

Евристика тут досить проста: виявляйте поля з певними іменами у певному порядку. Які саме, я не можу сказати, але це добре працювало для мене в Chrome та 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.

Мені довелося замінити <button type="submit">, <input type="submit">щоб змусити Дашлейна працювати. Не можу повірити, що це навіть річ, хоча ...
Брем Верстратен

3

Я також помітив, що Chrome не запропонує запам'ятати пароль, якщо форма входу все ще присутня після запиту на вхід, навіть якщо вона прихована на сторінці.

Думаю, він вважає, що дія входу не вдалася, і, отже, відмовляється зберігати недійсні облікові дані.

Побачено на Chrome 34.0.


1
Chrome 46 виправив свою неправильну поведінку, приховування форми після запиту ajax має бути достатньо. Див stackoverflow.com/a/33113374/810109
mkurz

3

Я б порадив подивитися вихідний код Firefox . Насправді це досить простий код.

Методи, які ви хочете переглянути, - це _onFormSubmit, _getFormFieldsі _getPasswordFields.

Ви навіть можете виявити, що ваша проблема полягає в тому, що вона виявила невідкриту помилку у Firefox;) https://bugzilla.mozilla.org/show_bug.cgi?id=1211780


0

На додаток до багато чого вже сказаного, я зрозумів, що поля введення не повинні бути "вимкненими". У нас був багатоступеневий логін, який спочатку запитує ім’я користувача, а потім, на наступному екрані, пароль. На цьому другому екрані ми повторили електронний лист, але вимкнули його, і це завадило Chrome et. ін. від розпізнавання як дійсне поле для імені користувача.

Оскільки ми дійсно хотіли зберегти це відключене поле введення, у нас з’явився такий хитрий спосіб обходу:

<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">

Я б не заходив так далеко, щоб рекомендувати це, але, можливо, це вказує комусь на щось у власному коді:

  1. Перший елемент відображає ім’я користувача у відключеному полі введення. Вимкнений не надсилається як частина форми, а вимкнений не розпізнається браузером.
  2. Другий елемент - це належне поле введення, з типом = "текст" та name / id = "ім'я користувача". Це визнано браузером. Щоб запобігти редагуванню користувачем, ми приховуємо його за допомогою CSS (display: none).

У ситуаціях, коли ви хочете введення, значення якого подано, але яке користувач не може змінити, ви можете спробувати "лише для читання" замість "вимкнено".
Девід Браун

0

Якщо у вас є, наприклад, два типи = текст у вашій формі перед типом введення = пароль, браузер виявить найближчий тип вводу = текст для вашого імені користувача.

Це не має значення інший вхід - це = ім'я користувача та ім'я = ім'я користувача

для вирішення цієї проблеми ви повинні ввести своє ім'я користувача, яке ви хочете зберегти, точно перед вашим вхідним паролем

Щасти :-)


-2

Основне ключове слово тут,

   <input type="password">

1
Спробуйте пояснити свою відповідь деякими деталями, оскільки це буде корисно для інших.
Ashish Duklan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.