7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirAdvent Calendar 2021

Day 22

③Elixirユーザ認証ライブラリ「phx_gen_auth」の本番向け改造ポイント:ページヘッダーの変更

Last updated at Posted at 2021-09-25

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

前回に引き続き、Phoenixユーザ認証ライブラリ「phx_gen_auth」のプロダクション向け改造ポイントとして、今回は、ページヘッダーの変更について解説します

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:ヘッダーの構成

未ログイン時のヘッダーは、下記の赤囲みのような出力を行います
image.png

ログイン済みの場合は、下記の緑囲みのような出力に切り替わります(ログアウトすると未ログイン時に戻ります)
image.png

この制御をしている対象ファイルは、以下の通りです

ファイルパス | 役割
-+-
lib/basic_web/templates/layout/_account_menu.html.heex | ログイン前/後のメニューリンクがある
lib/basic_web/templates/layout/root.html.heex | _account_menu.html.heexをrenderで読み込んでいる

各ファイルは、下記のような内容です

lib/basic_web/templates/layout/_account_menu.html.heex
<ul>
<%= if @current_account do %>
  <li><%= @current_account.email %></li>
  <li><%= link "Settings", to: Routes.account_settings_path(@conn, :edit) %></li>
  <li><%= link "Log out", to: Routes.account_session_path(@conn, :delete), method: :delete %></li>
<% else %>
  <li><%= link "Register", to: Routes.account_registration_path(@conn, :new) %></li>
  <li><%= link "Log in", to: Routes.account_session_path(@conn, :new) %></li>
<% end %>
</ul>

root.html.heex は、_account_menu.html.heex をrenderで読み込んでいます

lib/basic_web/templates/layout/root.html.heex
<!DOCTYPE html><body>
    <header>
      <section class="container">
        <nav>
          <ul>
            <li><a href="https://hexdocs.pm/phoenix/overview.html">Get Started</a></li>
            <%= if function_exported?(Routes, :live_dashboard_path, 2) do %>
              <li><%= link "LiveDashboard", to: Routes.live_dashboard_path(@conn, :home) %></li>
            <% end %>
          </ul>
          <%= render "_account_menu.html", assigns %>

③-2.調整例1:ヘッダーそのものを削除する

RegisterやLogin、メールアドレス表示などを、根本的にデザイン変更し、表示位置を変えたりしたい場合は、元々あるリンクを削除した方が都合が良いです

この対応は簡単で、root.html.heex の _account_menu.html をrenderしているところをコメントアウト or 削除するだけです

lib/basic_web/templates/layout/root.html.heex
<!DOCTYPE html><body>
    <header>
      <section class="container">
        <nav>
          <ul>
            <li><a href="https://hexdocs.pm/phoenix/overview.html">Get Started</a></li>
            <%= if function_exported?(Routes, :live_dashboard_path, 2) do %>
              <li><%= link "LiveDashboard", to: Routes.live_dashboard_path(@conn, :home) %></li>
            <% end %>
          </ul>
          <%= # render "_account_menu.html", assigns  # <-- comment-out here %>

もしくは、_account_menu.html の内容を空にするでもOKです

この通り、phx_gen_auth関連のリンクが、全て削除され、ここからのログインやユーザ登録等は一切できなくなります
image.png

なお、URL直打ちすれば、該当ページは利用できるので、ページの別場所からリンクを設定し、phx_gen_authの機能を各種ページ箇所にバラすことも可能です

一方、使用しないURLを機能させないようにしたい場合(後述のRegister削除など)は、下記のように、router.exからエントリーを削除します

lib/basic_web/router.ex
defmodule BasicWeb.Router do

  ## Authentication routes

  scope "/", BasicWeb do
    pipe_through [:browser, :redirect_if_account_is_authenticated]

# v-- comment-out start
    # get "/accounts/register", AccountRegistrationController, :new
    # post "/accounts/register", AccountRegistrationController, :create
    # get "/accounts/log_in", AccountSessionController, :new
    # post "/accounts/log_in", AccountSessionController, :create
    # get "/accounts/reset_password", AccountResetPasswordController, :new
    # post "/accounts/reset_password", AccountResetPasswordController, :create
    # get "/accounts/reset_password/:token", AccountResetPasswordController, :edit
    # put "/accounts/reset_password/:token", AccountResetPasswordController, :update
# ^-- comment-out end
  end

③-3.調整例2:ヘッダーからRegisterを削除する(招待制サイト向き対応)

たとえば、会員制サイトの中でも、招待制のサイトであれば、ユーザ自身によるユーザ登録を禁止している場合があります

一方、デフォルトのphx_gen_authは、ユーザ自身によるユーザ登録を許可しているため、都合が悪いです

しかも初期状態では、仮登録等を挟まないので、いきなりユーザ登録/ログインができてしまいます(なお、仮登録を有効にするカスタマイズは、次回以降のコラムで紹介予定です)

こういうケースでは、_account_menu.html.heex の方を直接いじって、Register リンクを削除します

lib/basic_web/templates/layout/_account_menu.html.heex
<ul>
<%= if @current_account do %>
  <li><%= @current_account.email %></li>
  <li><%= link "Settings", to: Routes.account_settings_path(@conn, :edit) %></li>
  <li><%= link "Log out", to: Routes.account_session_path(@conn, :delete), method: :delete %></li>
<% else %>
  <!--<li>--><%= # link "Register", to: Routes.account_registration_path(@conn, :new) %><!--</li>-->
  <li><%= link "Log in", to: Routes.account_session_path(@conn, :new) %></li>
<% end %>
</ul>

なお、HTML部分を削除するだけで無く、Registerのlink生成しているElixirコードもコメントアウト or 削除することをお忘れなく

これで、Registerリンクのみが消え、画面からのユーザ登録ができなくなります(URL直打ちも出来なくするには、router.ex 側も修正してください)
image.png

招待制のユーザ登録導線側の実装は、機会があれば、別途コラムで紹介します

最後に

今回は、「phx_gen_auth」のプロダクション向け改造ポイントの中でも、ナビゲーションとデザインに関係してくるページヘッダーの変更を行いました

ヘッダーの変更は、定義ファイルの位置さえ把握してしまえば、難しく無いかと思いますが、ページデザイン内にphx_gen_authの機能をバラす際には必須のテクニックとなります

Elixir/Phoenixで、会員制サイトのような、ユーザ認証付きWebサイトを開発する際は、phx_gen_authを活用するとハッピーになれますよ:kissing_heart:

なお、気が向いたら、上記を全てセッティングした会員制WebサイトのテンプレートをOSS化したいなぁって思っています … つまり、Elixir/Phoenixであれば、会員制Webサイトの構築をイチからやらなくて良くなります

次回は、phx_gen_authの各種ページデザインのカスタマイズをします

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?