ブラウザは、ユーザーにパスワードの保存を求めるタイミングをどのようにして知るのですか?


82

これは、私がここで尋ねた質問に関連してい ます。ブラウザにパスワードの保存を求めるプロンプトを表示するにはどうすればよいですか?

これが問題です。開発中のサイトのパスワードを保存するようにブラウザに要求することができません。(Firefoxでフォームを送信すると、「yoursite.comのパスワードを覚えていますか?はい/今はありません/決してありません」というバーが表示されることがあります)

Firefoxのこの機能(および同様の方法で動作することを望んでいる他のほとんどの最新のブラウザー)は謎のように思われるため、これは非常に苛立たしいことです。これは、ブラウザがコードや送信内容などを確認する手品のようなもので、ユーザー名(またはメールアドレス)フィールドとパスワードフィールドを備えたログインフォームのように「見える」場合は、保存する。

この場合を除いて、ユーザーが私のログインフォームを使用した後、そのオプションをユーザーに提供しておらず、それが私を苛立たせています。:-)

(Firefoxの設定を確認しました。このサイトのブラウザに「決して」とは言っていません。プロンプトが表示されるはずです。)

私の質問

Firefoxがユーザーに保存を求めるタイミングを知るために使用するヒューリスティックは何ですか?これはMozillaソースにあるので、答えるのはそれほど難しいことではありません(どこを見ればよいかわからないか、自分で掘り下げようとします)。私はまた、これに関するMozilla開発者からのブログ投稿や他の同様の開発者メモを見つけることができませんでした。

(SafariまたはIEでこの質問に答えても問題ありません。すべてのブラウザーが非常によく似たルールを使用していると思います。したがって、いずれかのブラウザーで機能させることができれば、他のブラウザーでも機能します。)

(*私の答えがCookie、暗号化、またはローカルデータベースにパスワードを保存する方法に関するその他のことと関係がある場合は、私の質問を誤解している可能性が高いことに注意してください。:-)


1
私は知らないよ。フォームはパスワードタイプフィールドのあるPOSTフォームですか?
zneak 2010年

2
はい、<form>タグでラップされており、フィールドの名前は「username」と「password」です。AJAXを使用して別のレイヤーとしてロードしますが、disqus.comもロードし(例を示すためだけに)、それらに最適です。そのため、ランダムに調整して何らかの形で役立つかどうかを確認するのではなく、ブラウザーがどのように考えているかを正確に調べたいと思います。
エリック

回答:


55

私が読んだものに基づいて、Firefoxはによってパスワードを検出すると思います form.elements[n].type == "password"(すべてのフォーム要素を繰り返し処理して)を検出し、パスワードフィールドの直前のテキストフィールドをフォーム要素で逆方向に検索してユーザー名フィールドを検出するます(詳細はこちら)。Javascriptで同様のことを試して、パスワードフィールドを検出できるかどうかを確認してください。

私の知る限り、ログインフォームはの一部である<form>必要があります。そうでない場合、Firefoxはそれを検出しません。id="password"パスワードフィールドに設定しても、おそらく害はありません。

それでも多くの問題が発生する場合は、Mozillaプロジェクトの開発者メーリングリストの1つに質問することをお勧めします(機能を設計した開発者からの回答を受け取ることもあります)。


2
それは素晴らしいです。ありがとう。それが私が探しているものです。
エリック

1
これはFirefoxで動作させるのに役立ちましたが、Chromeではうまくいきません。<フォームID = "あるmyForm"アクション= "#"> <入力されたID = "ユーザ名"> <入力されたID = "パスワード"タイプ= "パスワード"> </ form>を:これは私が使用しているフォームです
1.21ギガワット

3
@ 1.21gigawatts-これを行うための「標準的な」方法は(私の知る限り)ないので、ブラウザが異なれば少し異なる場合があります。ChromeのプロセスがFirefoxのプロセスとどのように異なるかはわかりませんが、Chromeのソースコードを調べれば理解できるかもしれません。Firefoxがどのようにそれを行ったかを私が知る唯一の方法は、彼らのコードを読むことでした。これは、誰かが大きなチャートに文書化する必要がある種類のものであり、各ブラウザがそれをどのように行うかをリストしています...
bta 2012年

3
パスワードマネージャーコードの作成者が2013年のブログ投稿で説明します-読む価値があります:blog.mozilla.org/dolske/2013/08/20/on-firefoxs-password-manager
dat

2
パスワードマネージャーのブログ投稿へのリンクを更新:dolske.wordpress.com/2013/08
Vsevolod Golovanov

17

私は同じ問題を抱えていて、解決策を見つけました:

  1. ブラウザにパスワードの保存を要求させるには、ユーザー名とパスワードボックスをフォームに入力し、そのフォームを実際に送信する必要があります。送信ボタンは、onclickハンドラーからfalseを返す可能性があります(したがって、送信は実際には発生しません)。

  2. ブラウザに以前に保存されたパスワードを復元させるには、入力ボックスがメインのHTMLフォームに存在し、JavaScriptを介して動的に作成されないようにする必要があります。フォームはdisplay:noneで作成できます。

パスワードはページが読み込まれるとすぐに入力され、セッション全体を通してそこに存在するため、挿入されたjavascriptで読み取ることができることに注意する必要があります。これにより、このような攻撃がさらに悪化します。これを回避するには、ログインするためだけに別のページに転送するのが合理的であり、このトピックを読み始めたすべての問題を解決します:)。部分的な解決策として、フォームの送信時にフィールドをクリアします。ユーザーがログアウトして再度ログインしたい場合、パスワードはブラウザーによって入力されませんが、それは私にとってはマイナーです。

ビリアム



Firefox 3.5およびIE8で動作し、Chromeでは動作しません(ポイント1が機能しません)。たぶん...本物でなければなりませ提出
user324356

user324356-フォームを「#」に設定してからmyForm.submit()を呼び出しましたが、Firefoxでは機能しましたがChromeではプロンプトが表示されません。
1.21ギガワット

1
fyi:このバグのためにChromeで使用するreturn falseか、event.preventDefault()これが機能しない場合:code.google.com/p/chromium/issues/detail
id =

これは、Firefoxで使用されている現在のアルゴリズムでは間違いなく重要です。パスワードマネージャーが「検索」するのはこれだけではありませんが、実際の送信なしではFirefoxパスワードマネージャーはトリガーされません。
日付2015

更新:Chrome46の誤った動作が修正されました。すべてが正常に機能するようになりました。stackoverflow.com/a/33113374/810109
mkurz 2015年

10

あなたは見ておくべきであるMozillaのパスワードマネージャのデバッグページとnsILoginManagerドキュメント(ちょうどFirefoxはパスワード管理を扱う方法の核心技術的な詳細について)拡張作家のため。そこにある回答やそこにリンクされている他のページを掘り下げて、パスワードマネージャーがサイトや拡張機能とどのように相互作用するかを知りたいと思っていた以上のことを見つけることができます。

(特に、パスワードマネージャーのデバッグドキュメントで指摘されているように、HTMLでオートコンプリートがオフに設定されていないことを確認してください。これにより、ユーザー名とパスワードを保存するプロンプトが抑制されます)


7

これは、Mac上のFirefox、Chrome、Safariで機能するようです。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はdisplay:noneに設定できます。iframeのsrcを設定しない場合、フォームを少なくとも1回送信するまで、プロンプトは表示されません。

次に、フォーム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あなたは解決策を思いついたのですか?一部のブラウザ(safari)では、ページはローカルホストやファイルシステムではなく、サーバー上にある必要があることに気付きました。
1.21ギガワット

1
Chrome46はその間違った動作を修正しました-iframe回避策はもう必要ありません。stackoverflow.com/a/33113374/810109
mkurz 2015年

6

Angular、Chrome、Firefoxで動作します:(私は何時間も検索してテストしました-Chromeの場合、フォームアクションパラメータ(#)が答えでした。@ 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は次のようになります

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

角度ディレクティブ(jqLit​​eを使用)

これは角度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がAngularログイン方式(200ms)によって少しタイムアウトする必要があることに気付きました-リダイレクトがパスワードマネージャーにとって速すぎる場合があるようです。
  • より良いbrowsercacheをクリア...すべての変更で

最新のクロム以来、pw-managerはたまにしかフォームに記入しません。また、pw managerがポップアップすることもあれば、ポップアップしないこともあります...現在はランダム化された関数のようです。
110maor 2014年

新しいFirefoxは、自動入力されたパスワードフィールドを無視します。triggerHandler( "input")が機能していません。これは、ネイティブイベント(document.createEvent)で解決できます-火をディスパッチします。
110maor 2014年

1
Chrome46はその間違った動作を修正しました-iframe回避策はもう必要ありません。stackoverflow.com/a/33113374/810109
mkurz 2015年

@ 110maorあなたの投稿を理解するのに長い時間がかかりました。私の編集があなたの意図に忠実であることを願っています。
jpaugh 2017

3

さて、私たちのサイトでは、「username」という名前のフォームフィールドの直後に「text」と入力し、その後に「password」という名前と「password」と入力したフィールドがうまくいくようです。


私には速すぎる!私の考えは正確に...(私は私の答えを削除しています)
ガネーシュシャンカール2010年

はい。それを試してみました。運がない。:-(私の理論では、ブラウザが気に入らない何かがページにある/ページにログインフォームがないと思わせる...
Eric

3

AJAXログインを使用している場合は、そのソースコードを確認してくださいhttps//gist.github.com/968927

これは、ログインフォームを非表示のiframeに送信することで構成されているため、IEとChromeは、ページをリロードしなくても実際のログインを検出できます。


Chrome46はその間違った動作を修正しました-iframe回避策はもう必要ありません。stackoverflow.com/a/33113374/810109
mkurz 2015年

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.

Dashlaneを機能<button type="submit"><input type="submit">せるには、に置き換える必要がありました。しかし、これが問題であるとは信じられません...
BramVerstraten20年

3

また、ログインリクエスト後もログインフォームが存在する場合、ページに非表示になっている場合でも、Chromeがパスワードを記憶することを提案しないことに気付きました。

ログインアクションが失敗したと考えているため、無効な資格情報の保存を拒否していると思います。

Chrome34.0で見られます。


1
Chrome 46はその間違った動作を修正し、ajaxリクエストの後にフォームを非表示にするだけで十分です。stackoverflow.com/a/33113374/810109
mkurz 2015年


0

すでに述べた多くのことに加えて、入力フィールドを「無効」にしてはならないことに気づきました。最初にユーザー名を要求し、次に次の画面でパスワードを要求するマルチステップログインがありました。その2番目の画面で、メールを繰り返しましたが、無効にしたため、Chromeなどが使用できなくなりました。al。ユーザー名の有効なフィールドとして認識されないようにします。

その無効な入力フィールドを本当に保持したかったので、このハッキーな回避策に行き着きました。

<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. 2番目の要素は適切な入力フィールドであり、type = "text"およびname / id = "username"です。これはブラウザによって認識されています。ユーザーが編集できないようにするために、CSS(display:none)で非表示にします。

値が送信されても​​ユーザーが変更できない入力が必要な場合は、「無効」ではなく「読み取り専用」を試してください。
デビッドブラウン

0

たとえば、入力type = passwordの前にフォームに2つのtype = textがある場合、ブラウザはユーザー名に最も近い入力type = textを検出します。

これは、別の入力がis = usernameおよびname = usernameであるかどうかは関係ありません。

この問題を解決するには、保存するユーザー名入力を入力パスワードの直前に配置する必要があります

幸運を :-)


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.