LoginSignup
3
0

More than 1 year has passed since last update.

PhoenixLiveViewを使用したmix phx.gen_authを詳しく見てみた【認証メール再送信編】②

Last updated at Posted at 2023-03-03

はじめに

この記事ではPhoenixのバージョン1.7.0を使用しています。

$ mix phx.new -v
Phoenix installer v1.7.0

前回の記事に引き続き、今回はアカウントの認証メール再送信を見ていきます。

以下はこのシリーズの目次です。

目次

生成されたファイルの確認

前回はアカウントの登録から認証するまでの生成されたファイルを確認しました。
今回は認証メールを再送信するための機能をまとめたファイルを確認します。

認証メール再送信

認証メール再送信をするためのurlは以下です。

http://localhost:4000/accounts/confirm

Screenshot from 2023-03-03 17-39-23.png

認証メール再送信に該当するソースコードは以下です。

auth_sample/lib/auth_sample_web/live/account_confirmation_instructions_live.ex
defmodule AuthSampleWeb.AccountConfirmationInstructionsLive do
  use AuthSampleWeb, :live_view

  alias AuthSample.Accounts

  def render(assigns) do
    ~H"""
    <.header>Resend confirmation instructions</.header>

    <.simple_form for={@form} id="resend_confirmation_form" phx-submit="send_instructions">
      <.input field={@form[:email]} type="email" label="Email" required />
      <:actions>
        <.button phx-disable-with="Sending...">Resend confirmation instructions</.button>
      </:actions>
    </.simple_form>

    <p>
      <.link href={~p"/accounts/register"}>Register</.link>
      |
      <.link href={~p"/accounts/log_in"}>Log in</.link>
    </p>
    """
  end

  def mount(_params, _session, socket) do
    {:ok, assign(socket, form: to_form(%{}, as: "account"))}
  end

  def handle_event("send_instructions", %{"account" => %{"email" => email}}, socket) do
    if account = Accounts.get_account_by_email(email) do
      Accounts.deliver_account_confirmation_instructions(
        account,
        &url(~p"/accounts/confirm/#{&1}")
      )
    end

    info =
      "If your email is in our system and it has not been confirmed yet, you will receive an email with instructions shortly."

    {:noreply,
     socket
     |> put_flash(:info, info)
     |> redirect(to: ~p"/")}
  end
end

うえから順に確認します。

まずはmountを確認します。

auth_sample/lib/auth_sample_web/live/account_confirmation_instructions_live.ex
def mount(_params, _session, socket) do
  {:ok, assign(socket, form: to_form(%{}, as: "account"))}
end

ソケットにformキーでアサインされている値は以下です。

%Phoenix.HTML.Form{
  source: %{},
  impl: Phoenix.HTML.FormData.Map,
  id: "account",
  name: "account",
  data: %{},
  hidden: [],
  params: %{},
  errors: [],
  options: [],
  index: nil,
  action: nil
}

フォーム用の構造体をアサインしていることになります。

次にrenderを確認します。

auth_sample/lib/auth_sample_web/live/account_confirmation_instructions_live.ex
def render(assigns) do
  ~H"""
  <.header>Resend confirmation instructions</.header>

  <.simple_form for={@form} id="resend_confirmation_form" phx-submit="send_instructions">
    <.input field={@form[:email]} type="email" label="Email" required />
    <:actions>
      <.button phx-disable-with="Sending...">Resend confirmation instructions</.button>
    </:actions>
  </.simple_form>

  <p>
    <.link href={~p"/accounts/register"}>Register</.link>
    |
    <.link href={~p"/accounts/log_in"}>Log in</.link>
  </p>
  """
end

ここで確認すべきはフォームで何を入力するかとフォームを送信した際にどのイベントを呼ぶのかです。
フォームで何を入力するかはメールアドレスです。送信先のイベントは"send_instructions"です。

次にフォーム送信先のイベント"send_instructions"を確認します。

auth_sample/lib/auth_sample_web/live/account_confirmation_instructions_live.ex
def handle_event("send_instructions", %{"account" => %{"email" => email}}, socket) do
  if account = Accounts.get_account_by_email(email) do
    Accounts.deliver_account_confirmation_instructions(
      account,
      &url(~p"/accounts/confirm/#{&1}")
    )
  end

  info =
    "If your email is in our system and it has not been confirmed yet, you will receive an email with instructions shortly."

  {:noreply,
   socket
   |> put_flash(:info, info)
   |> redirect(to: ~p"/")}
end

フォームから受け取るパラメータは以下です。

%{"account" => %{"email" => "taro@sample.com"}}

フォームから受け取ったメールアドレスでアカウントを取得します。

auth_sample/lib/auth_sample_web/live/account_confirmation_instructions_live.ex
account = Accounts.get_account_by_email(email)

アカウントが取得できた場合はAccounts.deliver_account_confirmation_instructions/2関数を実行します。
Accounts.deliver_account_confirmation_instructions/2前回の記事で解説したので詳しい解説は省略します。
Accounts.deliver_account_confirmation_instructions/2は認証用のトークンを生成し、メールを送信する関数です。

メールが送信できたらhome(http://localhost:4000)にリダイレクトしメッセージを表示させます。

では、まだ認証をしていないアカウントのメールアドレスを入力して「Resend confirmation instructions」ボタンを押してフォームを送信をします。

Screenshot from 2023-03-03 18-27-41.png

送信できたらhttp://localhost:4000/dev/mailboxにアクセスしてメールを確認します。

Screenshot from 2023-03-03 18-28-42.png

これでhttp://localhost:4000/accounts/confirm/xxxにアクセスして認証をすることができます。

終わり

今回もここまで読んで頂きありがとうございました。

次回はログインの部分について見ていきます。

3
0
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
3
0