この記事の概要
- phx.gen.htmlでpasswordフィールドをテンプレート生成する際には
form.html.erbのtext_fieldをpassword_fieldに変更する
問題の再現
こんな感じで適当にアプリケーション生成して、passwordフィールドを持つUserモデルを生成してみます
mix phx.new hoge
cd hoge
mix ecto.create
mix phx.gen.html User User users name:string password:string
忘れずにresources "/users", UserControllerをrouter.exに追加してmix ecto.migrateします
そうすると以下のようなform.html.eexが生成されると思います
<%= form_for @changeset, @action, fn f -> %>
<%= if @changeset.action do %>
<div class="alert alert-danger">
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<div class="form-group">
<%= label f, :name, class: "control-label" %>
<%= text_input f, :name, class: "form-control" %>
<%= error_tag f, :name %>
</div>
<div class="form-group">
<%= label f, :password, class: "control-label" %>
<%= text_input f, :password, class: "form-control" %>
<%= error_tag f, :password %>
</div>
<div class="form-group">
<%= submit "Submit", class: "btn btn-primary" %>
</div>
<% end %>
このままにしておくと?
mix phx.serverしてlocalhost:4000/users/newにアクセスしてみましょう

こんな感じでNameフィールドを空にしてあえてエラーが出るようにしてsubmitしてみます(この時点でパスワード表示されているのでマズイです)
すると以下のようなエラーが出ます
入力したパスワードが表示されてる!!
ちなみにパスワードハッシュ化してる場合はハッシュ化済みのパスワードが表示されるので、セキュリティ的に大変マズイです
解決策
こういう時にPhoenixは良い関数を用意してくれています。password_inputです!
先ほどのform.html.eexでpassword入力フォームのtext_inputとなっている部分をpassword_inputに変換します
<div class="form-group">
<%= label f, :password, class: "control-label" %>
<%= password_input f, :password, class: "form-control" %>
<%= error_tag f, :password %>
</div>
もう一度localhost:4000/users/newにアクセスしてみるとこうなります
ちゃんとパスワード隠れてますね!submitしてみると以下のようにちゃんとパスワードフィールドは空で返ってきます
text_input と password_input の違い
公式の説明を見てみると、入力したデータを再利用しないような配慮がされているみたいですね
For security reasons, the form data and parameter values are never re-used in password_input/3. Pass the value explicitly if you would like to set one.
password_input/3 | Phoenix.HTML.Form – Phoenix.HTML v2.12.0
text_input/3 | Phoenix.HTML.Form – Phoenix.HTML v2.12.0
まとめ
ちゃんとドキュメント把握しておくの大事ですね!
ちなみにshow.eexとかindex.eexにもパスワード表示されているので忘れずに削除しておきましょう笑
余談ですが本記事執筆時点(2018/10/25)でmix phx.serverすると{:plug_cowboy, "~> 1.0"}を追加するようにエラーが出るので、その場合はmix.exsに追加してmix deps.getすればOKです


