LoginSignup
10
5

②Elixirユーザ認証ライブラリ「phx_gen_auth」の本番向け改造点:バリデーションのカスタマイズ

Last updated at Posted at 2021-04-11

Elixir Digitalization Implementors/fukuoka.ex/kokura.exのpiacereです
ご覧いただいて、ありがとうございます :bow:

前回に引き続き、Phoenixユーザ認証ライブラリ「phx_gen_auth」のプロダクション向け改造ポイントとして、今回は、バリデーションのカスタマイズについて解説します

:ocean::ocean: Elixir ranked second on the Qiita Advent calendar :ocean::ocean:

In the programming language category ranking, Rust was 1st, Elixir was 2nd, Golang was 3rd, and all were modern programming languages.:laughing:
https://qiita.com/advent-calendar/2020/elixir
image.png

In addition, our Elixir community "fukuoka.ex" has won the top spot in the Web Technology category.
https://qiita.com/advent-calendar/2020/fukuokaex
image.png

本コラムの検証環境

本コラムは、以下環境で検証しています(Windowsで実施していますが、Linuxやmacでも動作する想定です)

なお、本コラム内で扱うPhoenix PJ名は「basic」、phx_gen_authのコンテキスト名は「Accounts」を前提にしています

②バリデーションのカスタマイズ

②-1:バリデーションメッセージの日本語化

バリデーションが実装されている下記をカスタマイズします

なお、ページ上部に出るエラーメッセージは、後続のシリーズで解説し、ここでは各項目のバリデーションメッセージの修正のみとなります

各バリデーション関数の利用場所(「lib/basic/accounts/account.ex」内)、バリデーション内容は、下記表の通りです(なお、PWはパスワードの略)

関数名 利用場所 バリデーション内容
validate_email ユーザ登録(/accounts/registration)
情報変更 [メアド変更](/accounts/settings)
メールアドレスの
必須チェック
validate_email ユーザ登録
情報変更 [メアド変更]
登録済みメールアドレス
との一致チェック
validate_password ユーザ登録
PWリセット実施(/accounts/reset_password)
情報変更 [PW変更](/accounts/settings)
PW必須チェック
validate_password ユーザ登録
情報変更 [PW変更]
PW長さチェック
validate_password ユーザ登録
情報変更 [PW変更]
PW文字種チェック
(コメントアウト済)
email_changeset 情報変更 [メアド変更] 登録済みメールアドレス
との一致チェック
password_changeset 情報変更 [PW変更] PWとPW確認の
入力一致チェック
validate_current_password 情報変更 [メアド変更、PW変更] 登録済みPW
との一致チェック

バリデーションメッセージの日本語化は、以下の通りです

デフォルトではコメントアウトされている英小文字/英大文字/記号を含めるチェックは、利用時だけ文言変更を行ってください

lib/basic/accounts/account.ex
defmodule Basic.Accounts.Account do

  defp validate_email(changeset) do
    changeset
-   |> validate_required([:email])
+   |> validate_required([:email], message: "必須項目ですのでご入力ください")
-   |> validate_format(:email, ~r/^[^\s]+@[^\s]+$/, message: "must have the @ sign and no spaces")
+   |> validate_format(:email, ~r/^[^\s]+@[^\s]+$/, message: "「@」がありません、もしくは半角スペースは使えません")
    |> validate_length(:email, max: 160)
-   |> unsafe_validate_unique(:email, Basic.Repo)
+   |> unsafe_validate_unique(:email, Basic.Repo, message: "すでに登録済みです")
    |> unique_constraint(:email)
  end

  defp validate_password(changeset, opts) do
    changeset
-   |> validate_required([:password])
+   |> validate_required([:password], message: "必須項目ですのでご入力ください")
-   |> validate_length(:password, min: 12, max: 72)
+   |> validate_length(:password, min: 12, message: "%{count}文字以上にしてください")
+   |> validate_length(:password, max: 72, message: "%{count}文字以内にしてください")
    # Examples of additional password validation:
-   # |> validate_format(:password, ~r/[a-z]/, message: "at least one lower case character")
+   # |> validate_format(:password, ~r/[a-z]/, message: "英小文字を含めてください")
-   # |> validate_format(:password, ~r/[A-Z]/, message: "at least one upper case character")
+   # |> validate_format(:password, ~r/[A-Z]/, message: "英大文字を含めてください")
-   # |> validate_format(:password, ~r/[!?@#$%^&*_0-9]/, message: "at least one digit or punctuation character")
+   # |> validate_format(:password, ~r/[!?@#$%^&*_0-9]/, message: "記号文字を含めてください")
    |> maybe_hash_password(opts)
  end

  def email_changeset(account, attrs) do
    account
    |> cast(attrs, [:email])
    |> validate_email()
    |> case do
      %{changes: %{email: _}} = changeset -> changeset
-     %{} = changeset -> add_error(changeset, :email, "did not change")
+     %{} = changeset -> add_error(changeset, :email, "変更ができません")
    end
  end

  def password_changeset(account, attrs, opts \\ []) do
    account
    |> cast(attrs, [:password])
-   |> validate_confirmation(:password, message: "does not match password")
+   |> validate_confirmation(:password, message: "パスワードが一致しません")
    |> validate_password(opts)
  end

  def validate_current_password(changeset, password) do
    if valid_password?(changeset.data, password) do
      changeset
    else
-     add_error(changeset, :current_password, "is not valid")
+     add_error(changeset, :current_password, "正しくありません")
    end
  end

②-2:バリデーションのカスタマイズ

たとえば、phx_gen_authのデフォルトは、パスワード長チェックが12文字以上80文字以内と、やたら長いので、下記のように、8文字以上16文字以内といった、適当な長さに変更できます

英小文字/英大文字/記号を含めるチェックもデフォルトで入っているので、必要に応じて解除してください

lib/basic/accounts/account.ex
defmodule Basic.Accounts.Account do

  defp validate_password(changeset, opts) do
    changeset
    |> validate_required([:password])
-   |> validate_length(:password, min: 12, max: 80)
+   |> validate_length(:password, min: 8, message: "%{count}文字以上にしてください")
+   |> validate_length(:password, max: 16, message: "%{count}文字以内にしてください")
    |> validate_length(:password, min: 12, max: 72)
    # Examples of additional password validation:
    # |> validate_format(:password, ~r/[a-z]/, message: "at least one lower case character")
    # |> validate_format(:password, ~r/[A-Z]/, message: "at least one upper case character")
    # |> validate_format(:password, ~r/[!?@#$%^&*_0-9]/, message: "at least one digit or punctuation character")
    |> maybe_hash_password(opts)
  end

その配下にある、元からコメントアウトされた行を解除すると下記のバリデーションが有効になります

下記は、PWに英字小文字を最低1文字は記入することを強制します

    |> validate_format(:password, ~r/[a-z]/, message: "at least one lower case character")

下記は、PWに英字大文字を最低1文字は記入することを強制します

    |> validate_format(:password, ~r/[A-Z]/, message: "at least one upper case character")

下記は、PWに数字もしくは特殊文字(!、?、@、#、$、%、^、&、*、_)を最低1文字は記入することを強制します

    |> validate_format(:password, ~r/[!?@#$%^&*_0-9]/, message: "at least one digit or punctuation character")

このように、validate_formatを使えば、任意の正規表現でバリデーションを追加することができます

validate_email に同様のvalidate_formatを追加すれば、メールアドレスに任意の正規表現でバリデーションを追加することもできます

他に利用可能な汎用バリデーションは、下記コラムをご参考ください

最後に

今回は、ユーザ認証ライブラリ「phx_gen_auth」のプロダクション向け改造ポイントのうち、バリデーションについて解説しました

phx_gen_authのバリデーションは、最初から割としっかり作り込まれていますが、日本語化と、細かいカスタマイズは、本コラムを参考にトライしてみてください

次回は、ページヘッダーの調整をします

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5