web-dev-qa-db-ja.com

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

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

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

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

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

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

私の質問

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

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

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

78
Eric

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

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

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

52
bta

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

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

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

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

ヴィリアム


17
user324356

Mozilla Password Manager Debugging ページと nsILoginManager docs を拡張機能ライター向けにご覧ください(Firefoxがパスワード管理を処理する方法の技術的な詳細のみ)。そこにある回答やそこにリンクされている他のページを掘り下げて、パスワードマネージャーがサイトや拡張機能とどのようにやり取りするかを知りたいと思っている以上のものを見つけることができます。

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

10
Nick Bastin

角度、クロム、Firefoxで私のために働く:(私は何時間も検索してテストした-for chromeフォームアクションパラメータ(#)が答えでした。 @ 1.21ギガワット 、ありがとう!!! answer は非常に貴重でした。)

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を使用)

これはangular 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 loginメソッド(200ms)で少しタイムアウトする必要があることを認識しました-リダイレクトは時々速すぎますパスワードマネージャー用。
  • ブラウザキャッシュをより明確に...変更するたびに
6
110maor

これは、Firefox、ChromeおよびMac上の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();

アクションはオプションで、オートコンプリートはオプションです。テストしていません。

:一部のブラウザーでは、ブラウザーが応答する前に、フォームはサーバー(ローカルホストではなく、ファイルシステムではない)上で実行されている必要があります。

したがって、この:

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

これではない:

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

6
1.21 gigawatts

また、Chromeは、ログインリクエストがページに表示されていなくても、ログインリクエスト後にログインフォームがまだ存在する場合、パスワードを記憶することを提案しません。

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

Chrome 34.0で見られます。

3
ZeWaren

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

3
spender

AJAX loginを使用している場合は、そのソースコードをご覧ください: https://Gist.github.com/968927

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

3
Adrien Joly

Firefoxソースコード をご覧になることをお勧めします。実際には非常に簡単なコードです。

見たいメソッドは_onFormSubmit_getFormFieldsおよび _getPasswordFields

あなたが抱えている問題は、Firefoxの未発見のバグであることに気付くかもしれません;) https://bugzilla.mozilla.org/show_bug.cgi?id=121178

3
WoodenKitty

ここでは、ヒューリスティックは非常に単純です。特定の名前のフィールドを特定の順序で検出します。どれかはわかりませんが、これは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.
2
user19878

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

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

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

がんばろう :-)

1
keivan kashani

すでに述べた多くのことに加えて、入力フィールドを「無効」にしないでください。最初にユーザー名を要求し、次に次の画面でパスワードを要求するマルチステップログインがありました。その2番目の画面では、メールを繰り返しましたが無効にしたため、Chrome et。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. 最初の要素は、無効な入力フィールドにユーザー名を表示します。 Disabledはフォームの一部として送信されず、disabledはブラウザーに認識されません。
  2. 2番目の要素は、type = "text"およびname/id = "username"の適切な入力フィールドです。これはブラウザによって認識されています。ユーザーが編集できないようにするために、CSSで非表示にします(display:none)。
0
hendrikbeck