Chapter 17

mix phx.gen.auth

koga1020
koga1020
2021.11.23に更新

mix phx.gen.auth

mix phx.gen.auth コマンドは、Phoenixアプリに柔軟性のある、構築済みの認証システムを生成します。このシンプルなジェネレーターにより、コードベースに認証機能を追加するという作業を素早く済ませ、アプリケーションが解決しようとしている現実の問題に集中できます。

はじめに

まずは、アプリのルート(umbrellaアプリの場合は apps/my_app_web)から以下のコマンドを実行してみましょう。

$ mix phx.gen.auth Accounts User users

これにより、Accounts.User というスキーマモジュールを持つ Accounts コンテキストが作成されます。最後の引数は、データベースのテーブル名やルートヘルパーの生成に使用するスキーマモジュールの複数形です。mix phx.gen.auth ジェネレーターは mix phx.gen.html と似ていますが、スキーマに追加するフィールドのリストを受け付けないことと、より多くのコンテキスト関数を生成することが異なります。

このジェネレーターは mix.exs に追加の依存関係をインストールしているので、それらを取得してみましょう。

$ mix deps.get

次に、マイグレートとテストが正しく実行できるように、config/ で開発環境とテスト環境のデータベース接続の詳細を確認する必要があります。そして、以下を実行してデータベースを作成します。

$ mix ecto.setup

テストを実行して、新しい認証システムが期待通りに動作することを確認しましょう。

$ mix test

そして最後に、Phoenixサーバーを起動して試してみましょう。

$ mix phx.server

開発者の責任範囲

Phoenixは、Phoenix自体にこれらのモジュールを組み込むのではなく、アプリケーションにこれらのコードを生成するので、ユーザーは認証システムを自由に変更することができ、ユースケースに合わせて最適なものを作ることができます。生成された認証システムを使用する際の注意点としては、生成された後は更新されないということです。したがって、mix phx.gen.auth の出力に改良が加えられた場合、その変更をアプリケーションに移植する必要があるかどうかを判断するのはユーザーの責任となります。セキュリティ関連やその他の重要な改善点は、 CHANGELOG.md ファイルやアップグレードノートに明示的かつ明確に記載されます。

生成されるコード

以下は、生成された認証システムに関する注意点です。

パスワードのハッシュ化

デフォルトのパスワードハッシュ化メカニズムは、Unixシステムでは bcrypt 、Windowsシステムでは pbkdf2 です。どちらのシステムも Comeoninインターフェイス を使用しています。

パスワードのハッシュメカニズムは --hashing-lib オプションでオーバーライドできます。以下の値がサポートされています。

* `bcrypt` - [bcrypt_elixir](https://hex.pm/packages/bcrypt_elixir)
* `pbkdf2` - [pbkdf2_elixir](https://hex.pm/packages/pbkdf2_elixir)
* `argon2` - [argon2_elixir](https://hex.pm/packages/argon2_elixir)

開発者の方には、3つの中でもっとも堅牢な argon2 の使用を検討されることをオススメします。デメリットとしては、argon2 はCPUとメモリをかなり消費するので、アプリケーションを実行するにはより強力なインスタンスが必要になります。

これらのライブラリの選択についての詳細は、Comeoninプロジェクトを参照してください。

アクセスを禁止する

生成されたコードには、現在のユーザーを取得したり、認証を要求したりするいくつかのプラグインを含む認証モジュールが同梱されています。たとえば、mix phx.gen.auth Accounts User users を実行したDemoというアプリには、DemoWeb.UserAuth というモジュールがあり、以下のようなプラグが含まれています。

  • fetch_current_user - 現在のユーザー情報があれば、それを取得します。
  • require_authenticated_user - fetch_current_user の後に起動され、カレントユーザーが存在し、認証されていることを要求します。
  • redirect_if_user_is_authenticated - 認証済みのユーザーが利用できないいくつかのページに使用します。

確認

生成された機能には、アカウント確認の仕組みが含まれており、ユーザーは通常、電子メールでアカウントを確認する必要があります。しかし、生成されたコードでは、アカウントがまだ確認されていないユーザーがアプリケーションを使用することを禁止していません。この機能を追加するには、Auth モジュールの require_authenticated_user をカスタマイズして、confirmed_at フィールド (および必要に応じてその他のプロパティ) をチェックする必要があります。

通知

生成されたコードは、アカウントの確認やパスワードのリセットなどのためにSMSやメールを送信するようなシステムとは統合されていません。その代わりに、単にメッセージを端末に記録します。生成後に適切なシステムと統合するのは開発者の責任です。

セッションのトラッキング

すべてのセッションとトークンは、別のテーブルで追跡されます。これにより、各アカウントで有効なセッションの数を追跡できます。必要に応じて、この情報をユーザーに公開することもできます。

なお、パスワードが変更されると (パスワードのリセットまたは直接変更)、すべてのトークンが削除され、すべてのデバイスで再ログインする必要があります。

ユーザー列挙攻撃

ユーザー列挙型攻撃では、攻撃者はアプリケーションに登録されているすべてのメールを列挙できます。たとえば、登録されているメールでパスワードを間違えてログインしようとした場合と、登録されていないメールでログインしようとした場合とで、異なるエラーが返ってきた場合、攻撃者はこの矛盾を利用して、どのメールにアカウントがあるのかを知ることができます。

生成された認証コードは、登録と更新のメールフォームを除く、すべてのエンドポイントで列挙型攻撃から保護します。列挙型攻撃に非常に敏感なアプリケーションの場合、独自の登録ワークフローを実装する必要があります。これは、多くのアプリケーションのワークフローとは大きく異なる傾向があります。

ケースセンシティブ

メール検索は、大文字小文字を区別しないように作られています。MySQLやMSSQLでは大文字小文字を区別しない検索がデフォルトです。SQLite3ではカラム定義で COLLATE NOCASE を使用して対応しています。PostgreSQLでは、citext 拡張を使用します。

注意: citext はPostgreSQL自体の一部であり、ほとんどのオペレーティングシステムやパッケージマネージャではPostgreSQLにバンドルされています。ほとんどの場合、mix phx.gen.auth が拡張子の作成を行い、追加の作業は必要ありません。万が一、パッケージマネージャが citext を別のパッケージに分割している場合は、移行時にエラーが発生しますが、おそらく postgres-contrib パッケージをインストールすることで解決できます。

テストの同時実行

PostgreSQLのように同時実行テストをサポートしているデータベースを使用している場合、生成されたテストは同時に実行されます。

その他の mix phx.gen.auth について

異なるパスワードハッシュライブラリの使用、Webモジュールの名前空間のカスタマイズ、バイナリIDタイプの生成、デフォルトオプションの設定、テーブル名のカスタムなどの詳細については、mix phx.gen.auth を確認してください。

その他のリソース

以下のリンクには、この生成コードの動機や設計に関する詳細情報があります。