状況
パスワードリセットを行おうとする、tokenが不正ですと言われ、更新ができない。
クライアント環境
OSバージョン: Mac Sierra 10.12.6
ブラウザ: Safari 11.0.1
サーバ環境
OS: Red Hat Enterprise 6.2 (古くて恥ずかしい)
DB: MySQL 5.5.13
言語: ruby2.1(こっちも古くて恥ずかしい) Rails 4.1.0(これもry)
現象
Mac Chrome, Windows Edge, Mac Safari 10.1.Xなどで確認し、再現できなかったが、偶然、同一バージョンで動作確認した際に再現できたので、再現内容を一部キャプチャをつけながら、報告します。
- Safari 11.0.1を使用して、ログインを行いパスワードを保存する。
- ログインセッションのタイムアウトまで待つ。
- ログインが必要なページへアクセスし、ログインフォームが表示され、ログインフォームにログインIDとパスワードが入力されていることを確認する。
ログイン画面(Safari)
※ キャプチャの下部に表示されているhtmlは、Safariの開発ツールを表示し、要素を表示しています。
4. パスワードのリセットへ進み、パスワードリセットのメールを送る(キャプチャ上では、パスワードをお忘れの方はこちらのリンク)
5. メールに記載されたURLから、サイトへアクセスする。
驚愕的なのが、input[name="user[reset_password_token]"]の値が、ログイン画面でautocompleteで補完されているアカウント名になっていること
もちろんChromeでは、tokenの値を上書きするようなことはない
対応策
1. autocomplete=offを指定する
2. 順番を変えてみる。
3. name属性を変更する。(user[reset_password_token] -> user[test])
4. name属性を変更する。(user[reset_password_token] -> reset_password_token)
効果あり(が、Railsを利用しているサイトのため、多分に漏れずdevise Gemを利用しているため、対応が苦しい。)
5. reset_password_tokenを二つ設置する。
効果あり(同じ名前のパラメータが二つ送られるが、URLパラメータは後勝ちなので、正常に動作する)
6. type="text"にし、style="display:none;"を指定する。
効果あり(理由はわからないが、hidden属性のautocomplete=offは効果ないが、text属性のautocomplete=offは効果がある模様)
結論: 上記の6つの方法が検討され、キモいが5番を選択することにしました。
6番も悪くないが、いつどのバージョンで、text属性のtokenも上書きされる可能性があることが配慮され、安全そうな6番になりました。
最終結果: 5番でリリースしようと思ったら、もっと良い方法を同僚のYさんが提案してくれました。
ほんとだ!!!!!! id属性を消すと値が上書きされない!!!!
name属性ではなく、id属性をみて、上書きするのか、なるほど。
ほんと勉強になった。