Как браузер знает, когда предложить пользователю сохранить пароль?
Это связано с вопросом, который я задал здесь:
Как я могу заставить браузер запрашивать сохранение пароля?
это проблема: я не могу получить мой браузер, чтобы предложить мне сохранить пароль для сайта, который я разрабатываю. (Я говорю о панели, которая появляется иногда, когда вы отправляете форму в Firefox, в которой говорится: "запомните пароль для yoursite.com да / не сейчас / никогда")
Это очень неприятно, потому что эта функция Firefox (и большинство других современные браузеры, которые, я надеюсь, работают подобным образом) кажется загадкой. Это похоже на волшебный трюк, который делает браузер, где он смотрит на ваш код, или то, что вы отправляете, или что-то еще, и если он "выглядит" как форма входа с полем имени пользователя (или адреса электронной почты) и полем пароля, он предлагает сохранить.
за исключением этого случая, когда он не предлагает моим пользователям эту опцию после того, как они используют мою форму входа, и это делает меня сумасшедшим. : -)
(Я проверил настройки Firefox-- I не сказали браузеру "никогда" для этого сайта. Это должно быть подсказкой.)
у меня вопрос
каковы эвристики, которые Firefox использует, чтобы знать, когда он должен предложить пользователю сохранить? Это не должно быть слишком сложно ответить, так как это прямо там, в источнике Mozilla (я не знаю, где искать, иначе я бы попытался выкопать его сам). Мне также не повезло найти сообщение в блоге или какую-либо другую подобную заметку разработчика от разработчиков Mozilla о этот.
(Я был бы в порядке с ответом на этот вопрос для Safari или IE; я бы предположил, что все пользователи браузеров очень похожи на правила, поэтому, если я могу заставить его работать в одном из них, он будет работать в других.)
(* обратите внимание, что если ваш ответ Мне имеет какое-либо отношение к cookies, шифрованию или чему-либо еще, что касается того, как я храню пароли в своей локальной базе данных, велики шансы, что вы неправильно поняли мой вопрос. : -)
13 ответов:
основываясь на том, что я прочитал, я думаю, что Firefox обнаруживает пароли по
form.elements[n].type == "password"(итерация по всем элементам формы), а затем обнаруживает поле имени пользователя путем поиска в обратном направлении через элементы формы для текстового поля непосредственно перед полем пароля (подробнее здесь). Вы можете попробовать что-то подобное в Javascript и посмотреть, сможете ли вы обнаружить поле пароля.из того, что я могу сказать, ваша форма входа должна быть частью
<form>или Firefox не обнаружит оно. Установкаid="password"на поле пароля, вероятно, тоже не повредит.Если это все еще дает вам много проблем, я бы рекомендовал спросить в одном из списков рассылки разработчиков проекта Mozilla (вы можете даже получить ответ от разработчика, который разработал эту функцию).
У меня была такая же проблема и я нашел решение:
чтобы браузер попросил сохранить пароль, поля Имя пользователя и пароль должны быть в форме, и эта форма должна быть фактически отправлена. Кнопка отправки может возвращать false из обработчика onclick (поэтому отправка на самом деле не происходит).
чтобы браузер восстановил ранее сохраненный пароль, поля ввода должны существовать в основной форме HTML и не создаваться через javascript динамически. Форма может быть создана с помощью display: none.
необходимо отметить, что пароль заполняется сразу после загрузки страницы и присутствует там в течение всего сеанса, поэтому его можно прочитать с помощью введенного javascript: это делает такие атаки намного хуже. Чтобы этого избежать, переадресация на отдельную страницу просто для входа в систему разумна, и это решает все проблемы, для которых вы начали читать эту тему :). В качестве частичного решения я ясно поля при отправке формы - если пользователь выходит из системы и хочет снова войти в систему, пароль не заполняется браузером, но это незначительно для меня.
Viliam
вы должны посмотреть Mozilla Password Manager Debugging страница и nsILoginManager документы для авторов расширений (только для мелких технических деталей того, как Firefox работает с управлением паролями). Вы можете копаться в ответах там и на других страницах, связанных там, чтобы узнать больше, чем вы, вероятно, когда-либо хотели знать, как менеджер паролей взаимодействует с сайтами и расширениями.
(в частности, как указано в пароле диспетчер отладки doc, убедитесь, что у вас нет автозаполнения в вашем html, так как это будет подавлять запрос на сохранение имени пользователя и пароля)
это, кажется, работает для 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.htmlhttp://localhost/myPage.htmlfile://directory/myPage.html
работает для меня с angular, chrome, firefox: (я искал и тестировал в течение нескольких часов-для chrome параметр действия формы (
#) был ответ. @1.21 гигаватт, спасибо!!! Ваш ответ была неоценима.)форма
firefox 30.0 - не требуется скрытая кнопка iframe и submit (как показано ниже), но требуется директива "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 выглядит как
<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 мс) - it кажется, перенаправление иногда слишком быстро для менеджера паролей.
- лучше очистить browsercache... с каждым изменением
ну, на наш сайт, поле формы с именем "Имя пользователя" типа " текст "сразу же после поля с именем" пароль "и типа" пароль", кажется, сделать трюк.
Если вы используете AJAX login, взгляните на этот исходный код:https://gist.github.com/968927
Он состоит из отправки формы входа в скрытый iframe, так что IE и Chrome могут обнаружить фактический логин, без необходимости перезагрузки страницы.
Я также заметил, что Chrome не будет предлагать запомнить пароль, если форма входа все еще присутствует после запроса на вход, даже если она скрыта на странице.
Я думаю, что он считает, что действие входа в систему не удалось и, таким образом, отказываются хранить недействительные учетные данные.
видно на Chrome 34.0.
эвристика здесь довольно проста: обнаружение полей с определенными именами в определенном порядке. Какие из них, я не могу сказать, но это отлично работало для меня в 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.
Я бы рекомендовал смотреть на!--4-- > исходный код Firefox. Это на самом деле довольно простой код.
методы, которые вы хотите посмотреть на это
_onFormSubmit,_getFormFieldsи_getPasswordFields.возможно, вы даже обнаружите, что проблема, с которой вы столкнулись, - это нераскрытая ошибка в Firefox;)https://bugzilla.mozilla.org/show_bug.cgi?id=1211780
Если у вас есть, например, два типа=текст в форме перед типом ввода=пароль, Браузер определяет ближайший тип ввода=текст для вашего имени пользователя.
Это не имеет значения другой вход имеет = имя пользователя и имя=имя пользователя
для решения этой проблемы вы должны ввести свое имя пользователя, которое вы хотите сохранить точно перед вашим паролем ввода
Удачи :-)
в дополнение к тому, что уже было сказано, я понял, что поля ввода не должны быть "отключены". У нас был многоступенчатый логин, который сначала запрашивает имя пользователя, а затем, на следующем экране, пароль. На этом втором экране мы повторили электронное письмо, но отключили его, и это предотвратило 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">Я бы не пошел так далеко, чтобы рекомендовать это, но, возможно, это указывает кому-то на что-то в их собственном коде:
- первый элемент отображает имя пользователя в отключенном поле ввода. Disabled не отправляется как часть формы, а disabled не распознается браузером.
- второй элемент-это правильное поле ввода, с типом = " текст "и name/id = "имя пользователя". Это распознается браузером. Для того чтобы предотвратить потребителя от редактирования мы скрываем его с помощью CSS (display:none).
Comments