ゆずめも

メモ的なブログです。主に勉強した事について書いてます。

ブラウザのパスワード管理機能に覚えさせるものの指定

ユーザー登録を作っていて、登録時にブラウザに認証情報を保存した場合に保存される情報が意図したものではなく、IDではないものをIDとして保存してしまう問題に出会ったメモ。

急ぎの方は「まとめ」まで飛ばしてください。

題材のformと問題の解説

メールアドレスとパスワードだけを登録するシンプルなフォームだと以下の感じだと思う。

<form>
    <input type="email" name="email" />
    <input type="password" name="password">
  </form>

作っていたものはここの間に別のinputが入る。

<input type="email" name="email" />
<input type="text" name="hoge" />
<input type="password" name="password">

この別のinputが入るとブラウザがhogepasswordをブラウザに保存してしまって、ログインしようとした時にIDとして使用しているメールアドレスではなくhogeの入力内容が自動入力されてしまい、ログインできない。

ブラウザの挙動

ちょっと話がずれるんですがinput type=passwordにはautocomplete属性というものがあります。

developer.mozilla.org

これのnew-passwordを設定してあげるとパスワードのinputにカーソルを合わせるとブラウザがパスワードをレコメンドしてくれるというものがあり、usernameというのがあります。

"username"
ユーザー名またはアカウント名。 https://developer.mozilla.org/ja/docs/Web/HTML/Attributes/autocomplete

これをブラウザに設定すると解決するかと思ったんですが、残念ながらそんな銀の弾丸はなかったので、自分が確認したブラウザの挙動を箇条書きで

chrome

  • autocomplete='username'を見て判断してくれる
  • autocomplete='username'がない場合はinputで判断してる
    • その時display:noneされたinputは無視

firefox

  • 直前のinputで判断してる?
    • display:noneなinputを無視しない
  • autocomplete='username'は無視してる?

まとめ

今回の場合開発しているフォームの順番を入れ替えることは大人の事情ですぐにはできず、Reactを利用しているのでdisplay: noneに設定したinputにemailと同じvalueを設定するのは何も難しくない*1。なのでパスワードの直前に見えないinputを作成し、autocomplete='username'を設定すると両ブラウザでメールアドレスとパスワードが意図した通りに保存された。

<input type="email" name="email" />
<input type="text" name="hoge" />
<input type="email" name="email" style={{display: none}} autocomplete="username"/>
<input type="password" name="password" autocomplete="new-password">

chromeというかchromiumのものはchromiumのサイトで検索したらそれっぽいのが出てきたんだけど、firefox, safariの判定の仕様というかどういう風にform作ればいいかみたいなドキュメントがどこにあるのかよくわからなくて、知ってる人いたら教えてほしい。

参考

*1:valueの設定は面倒なので省略してます