Open4

WebSavedata: 生成したtokenをパスワードマネージャーに突っ込みたい

okuokuokuoku

予想

↑のベストプラクティスに フォームが正常に送信されることを確認する という項があって、

フォームが送信されたことをパスワードマネージャーが理解できるようにします。これを行う方法は 2 種類あります。

  • 別のページに移動する。
  • History.pushState() または History.replaceState() を使ってナビゲーションをエミュレートし、パスワードフォームを削除します。

とある。前者は無理なので後者を実装すべきと言える。つまり、

  • form 内に password がある <div> を用意する
  • onLoad 以降に、生成したtokenの文字列で password の value を設定する
  • button にJavaScriptアクションを紐付ける
  • ボタンを押したら replaceState() して <div> の中身を消す

とすれば、パスワードマネージャーは保存UIを出してくれるのではないだろうか。

okuokuokuoku

フォームの設計

... こういう感じか。。?

<form id="token_saver">
  <input id="tagname" type="text" autocomplete="username"/>
  <input id="token" type="password" autocomplete="current-password"/>
  <input type="submit" value="Save Token..." />
</form>

とりあえずhookだけなら、

const tokensaverEl = document.getElementById("token_saver");
tokensaverEl.addEventListener("submit", done);

function done(e){
  console.log("done",e);
  e.preventDefault();
}
okuokuokuoku

たしかに出る (Safari以外)

https://codepen.io/okuoku/pen/yLGQNBL

<div id="token_saver_wrapper">
  <form id="token_saver">
    <input id="tagname" type="text" autocomplete="username" />
    <input id="token" type="password" autocomplete="current-password" />
    <input type="submit" value="Save Token..." />
  </form>
</div>
const wrapperEl = document.getElementById("token_saver_wrapper");
const tokensaverEl = document.getElementById("token_saver");
tokensaverEl.addEventListener("submit", done);

function done(e){
  console.log("done",e);
  // Clear form
  wrapperEl.innerHTML = "";
  // Navigate
  history.replaceState(null, ""); // FIXME: Async.
  e.preventDefault();
}

ダミーのログインフォームを<div> で囲んでおき、消してからreplaceStateする。

Chrome

Chromeのパスワードマネージャーはコレでトリガできるようだ。

Firefox

Firefoxもちゃんと出た。

1 Passwordを入れてたからか、Webサイトのログイン情報とパスワードを保存する のチェックが外れてたので入れておく必要があった。

Safari

トリガーしない! 。というわけでこれはダメだな。。殆どSafariのためにやってるようなもんなのに。。

Bugzillaに当時のSafariでは動いていたらしいコードがある https://bugzilla.mozilla.org/show_bug.cgi?id=1287202#c23 。これは location.href への書き込みで飛ばす方式。

ただ、 http://www.demo.amitjakhu.com/login-form/ のように期待通り動作するフォームもある。 ...実際にPOSTしないといけない。。?

Safari(というか大抵のブラウザ)はCredential Management APIを実装しているので、それを使って保存するのが良いだろうか。。

1 Passwordのブラウザ機能拡張

1Passwordはボタンを押しても保存プロンプトは出ない。1Passwordでは今回のような実装の場合は遷移する にパスワードを覚えさせる必要がある。また 1Passwordのブラウザ拡張はブラウザ標準のパスワードマネージャを無効化する ため、この点についてはトークン保存画面でフォローする必要がありそうだ。