LoginSignup
23
2

More than 1 year has passed since last update.

[Elixir] Phoenix1.7で入るphx.gen.authのLiveView化を掘り下げてみる

Last updated at Posted at 2022-12-21

この記事は Elixir Advent Calendar 2022 カレンダー1の22日目です。昨日は @torifukukaiou さんでした!


Phoenix1.6で mix phx.gen.auth が使えるようになり、コマンド一発で認証システムを実装できるようになりました :tada: が、LiveView実装ではないので、アカウント周りだけ別でUI実装しないといけなかったり、他がLiveView実装だとController(非LiveView)と行き来しないといけなかったりと、少し不便でした。

そんな中、Phoenix1.7でphx.gen.authがLiveView化するとの情報が!ということで、まだRCではありますが、phx.gen.authで生成されるLiveView周りのコードを見ていきます :eye::eye:

公式ドキュメント(HexDocs)を見比べてみる

Phoenixの公式ドキュメントでは、「GUIDES」と「MIX TASKS」のそれぞれに phx.gen.auth についての解説ページがあります。

GUIDES MIX TASKS
1.6.15 https://hexdocs.pm/phoenix/1.6.15/mix_phx_gen_auth.html https://hexdocs.pm/phoenix/1.6.15/Mix.Tasks.Phx.Gen.Auth.html
1.7.0-rc.0 https://hexdocs.pm/phoenix/1.7.0-rc.0/mix_phx_gen_auth.html https://hexdocs.pm/phoenix/1.7.0-rc.0/Mix.Tasks.Phx.Gen.Auth.html

Phoenix1.7での変更点を含め細かい違いはありますが、LiveView化については特に言及されていません。単に更新が追いついていないだけでしょうか :thinking:

Phoenix1.7.0-rc.0のプロジェクトを作成する

本題ではないのでさらっと。途中のYes/NoはすべてYesを選択しましょう。

docker run --rm -it -p 4000:4000 elixir:1.14.2-alpine sh
# 以下、Dockerコンテナ内でのコマンド実行
mix archive.install hex phx_new 1.7.0-rc.0
mix phx.new sample --database sqlite3
cd sample
apk add build-base inotify-tools
sed -i -e 's|{127, 0, 0, 1}|{0, 0, 0, 0}|' config/dev.exs
mix ecto.create
mix phx.server

これで http://localhost:4000 にアクセスできるようになります。

実際に mix phx.gen.auth を実行してみる

Context名が Accounts 、Schema名が User 、テーブル名が users となるように実行します。

mix phx.gen.auth Accounts User users
出力その1
An authentication system can be created in two different ways:
- Using Phoenix.LiveView (default)
- Using Phoenix.Controller only
Do you want to create a LiveView based authentication system? [Yn]

LiveViewを使うかどうか聞かれましたね!今回はYesを選択しましょう。

出力その2
(ファイルを作成するログがたくさん出るが、省略)

Please re-fetch your dependencies with the following command:

    $ mix deps.get

Remember to update your repository by running migrations:

    $ mix ecto.migrate

Once you are ready, visit "/users/register"
to create your account and then access "/dev/mailbox" to
see the account confirmation email.

とりあえず、言うとおりにコマンドを実行し、Phoenixを起動しましょう。

mix deps.get
mix ecto.migrate
mix phx.server
アカウント登録 ログイン メールアドレス/パスワード変更 パスワードリセット
image.png image.png image.png image.png

これだけの機能がコマンド一発でできあがるのはステキですね :sparkles:

ここまでのソースコードをGitHubにアップしています。ビジネスロジックはPhoenix1.6までと変わらないので今回はLiveView周りだけを見ていきますが、興味がある方は他のコードも見てみてください :muscle:

ルーティング

lib/sample_web/router.ex

アカウント周りの記述がいろいろと追加されていますが、中でも53・67・79行目の live_session に注目します。前からある機能ではありますが、LiveViewのマウント時に実行される関数を指定できます。例えば

live_session :require_authenticated_user,
  on_mount: [{SampleWeb.UserAuth, :ensure_authenticated}] do
  ...
end

という記述がある場合、ブロック内で指定したLiveViewの mount/3 の前に SampleWeb.UserAuth.on_mount/4 が実行されます。第一引数は :ensure_authenticated で、該当のコードを見ると「ログインしていなければLiveViewのマウントはされずにログイン画面にリダイレクトする」という動きになっています。

アカウント登録

lib/sample_web/live/user_registration_live.ex

アカウント登録に成功後、63行目で trigger_submit をtrueにすることで phx-trigger-action 属性が働き/users/log_in?_action=registered 宛にForm Submitが発生します。なぜこんな回りくどいことを...と思いつつも、ログインを見てみましょう。

ログイン

lib/sample_web/live/user_login_live.ex

ログイン処理がどこにもないぞ...?と最初は思いましたが、18-40行目をよ〜く見てみると、 simple_form コンポーネントは使われていますが実態としては普通のformタグになります。そのため、「Sign in」ボタンを押すと /users/log_in 宛にForm Submitが発生し、 SampleWeb.UserSessionController#create/2 が呼ばれます。

lib/sample_web/controllers/user_session_controller.ex の27行目がセッションにアクセストークンを入れているコードになります。なぜこんな回りくどい仕組みになっているかというと、おそらくですが、LiveViewとController(非LiveView)の両方で同一のログイン状態を扱うためのつくりなんだろうな〜と思っています。

メールアドレス/パスワード変更

lib/sample_web/live/user_settings_live.ex

1画面に複数のフォームがありますが、ここは普通のLiveView実装ですね。特に気になるところはありません。

パスワードリセット

lib/sample_web/live/user_forgot_password_live.ex

ここも普通のLiveView実装ですが、パスワードリセットの流れは

  1. パスワードリセット対象アカウントのメールアドレスを入力
  2. 届いたメール本文中のURLにアクセス
  3. lib/sample_web/live/user_reset_password_live.ex で新しいパスワードを設定

というよくある流れです。パスワードリセットが完了するとログイン画面に遷移してログインするように促されますが、単にリダイレクトするだけなので特別なことはないですね。

最後に

私の観測範囲内では、認証ライブラリというとブラックボックスっぽくなっていてカスタマイズするのに苦労するものが多い印象ですが、phx.gen.authはコードジェネレータなので実装を追いやすくカスタマイズも自由にできます。以前仕事でphx.gen.authを使ったときはLiveView化する余裕はありませんでしたが、今後はLiveViewアプリ開発がより一層捗りそうです :smirk:

23
2
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
23
2