前回(第1回)では、DockerとTablerを使ったRails開発環境に、定番の認証GemであるDeviseをインストールし、初期設定、Userモデルの作成、そして認証関連のURL(/admin/sign_inなど)を/admin配下に設定しました。Deviseを動かすための土台はできましたが、まだユーザーが実際にログインしたり、アカウントを作成したりすることはできませんでした。
この第2回では、いよいよ実際にユーザー認証機能を「使える」状態にします!具体的には以下の内容を進めます。
devise_forによって生成されたルーティングを確認します。- ユーザーがアカウントを新規登録(サインアップ)できることを確認します。
- 登録したアカウントでログイン(サインイン)、そしてログアウト(サインアウト)できることを確認します。
- Deviseが提供する便利なヘルパーメソッドを使い、ログイン状態に応じて表示を変えたり、アクセス制御をしたりする方法を学びます。
この記事を読み終えれば、あなたのアプリケーションでDeviseによる基本的な認証フローが一通り動作し、その仕組みを理解できるはずです。
前提となる開発環境
この記事は、以下の環境が整っていることを前提としています。
- DockerおよびDocker Compose
-
アプリケーションとデータベースなどがコンテナ管理されている。
- Tablerレイアウト
-
Tabler UIキット が導入済みで、
app/views/layouts/admin.html.erb等の管理画面用レイアウトがある。 - Devise導入済み
-
第1回の内容に従い、Devise Gemがインストールされ、初期設定、Userモデル生成、DBマイグレーションが完了し、認証URLが
/admin配下に設定されている。 - Flashメッセージ表示
-
レイアウトに
<%= render "shared/flash_messages" %>が設置されている。
Step 1: Deviseルーティングの確認
まず、第1回で config/routes.rb に設定した devise_for が、実際にどのようなURLパスを生成しているか確認しましょう。Railsコンテナ内で以下のコマンドを実行します。
# devise に関連するルーティングを表示
bin/rails routes | grep devise出力結果の中に、以下のような /admin から始まるパスが含まれているはずです(scope '/admin' と path: '', path_names の設定に基づきます)。
new_user_session GET /admin/sign_in(.:format) # ログインフォーム表示
user_session POST /admin/sign_in(.:format) # ログイン処理
destroy_user_session DELETE /admin/sign_out(.:format) # ログアウト処理
user_password POST /admin/password(.:format) # パスワードリセットメール送信
new_user_password GET /admin/password/new(.:format) # パスワードリセット要求フォーム
edit_user_password GET /admin/password/edit(.:format) # パスワード再設定フォーム
user_password PATCH /admin/password(.:format) # パスワード更新処理
PUT /admin/password(.:format) # パスワード更新処理
POST /admin/password(.:format) # パスワードリセットメール送信
cancel_user_registration GET /admin/cancel(.:format) # サインアップキャンセル
new_user_registration GET /admin/sign_up(.:format) # サインアップフォーム表示
edit_user_registration GET /admin/edit(.:format) # アカウント編集フォーム表示
user_registration PATCH /admin(.:format) # アカウント更新処理
PUT /admin(.:format) # アカウント更新処理
DELETE /admin(.:format) # アカウント削除処理
POST /admin(.:format) # サインアップ処理これらのパスを使って、実際に認証機能を試していきます。
Step 2: サインアップ機能の実装と確認
ユーザーが自身のアカウントを作成できるようにします。
- 1. 開発サーバーを起動(まだ起動していない場合)
-
bash docker compose up -d - 2. サインアップページへアクセス
-
- 表示内容
-
Deviseのデフォルトのサインアップフォーム(Email, Password, Password confirmation入力欄)が表示されます。
- 注意
-
第1回の最後で触れた通り、この時点では管理画面のTablerレイアウトは適用されていません。これは、Deviseのコントローラーがデフォルトのレイアウトを使用するためです。レイアウト適用とフォームのカスタマイズは次回の記事で行います。
- アカウント作成
-
フォームに有効なメールアドレスと、パスワード(確認用も同じもの)を入力して送信ボタンをクリックします。
- 結果確認
-
成功すればリダイレクト、失敗すればエラーメッセージが表示されます。
- 結果確認
-
- 成功時
-
デフォルトではアプリケーションのルートパス (
root_pathで設定したパス) にリダイレクトされ、「アカウント登録が完了しました。」(Welcome! You have signed up successfully.) のようなnoticeFlashメッセージが表示されるはずです。 - 失敗時
-
パスワードが短い、確認用パスワードが違う、Email形式が不正などのバリデーションエラーがあれば、フォームページが再表示され、エラー内容を示す
alertFlashメッセージが表示されます。(これは:validatableモジュールによるものです)
- DB確認 (任意)
-
Railsコンソール (
bin/rails c) でUser.countやUser.lastを実行し、ユーザーがデータベースに正しく保存されたことを確認できます。
これで、ユーザー登録機能が動作することが確認できました。
Step 3: ログイン (サインイン) と ログアウト (サインアウト) を試す
次に、登録したアカウントでログインし、その後ログアウトできるかを確認します。
- 1. サインインページへアクセス
-
ブラウザで
http://localhost:3000/admin/sign_inにアクセスします。デフォルトのサインインフォームが表示されます - 2. ログイン試行
-
- 成功
-
Step 2で登録したメールアドレスとパスワードを入力し、送信します。
成功すると、デフォルトでルートパスにリダイレクトされ、「ログインしました。」(Signed in successfully.) のnoticeFlashメッセージが表示されます。 - 失敗
-
情報が間違っている場合、サインインページが再表示され、「メールアドレスまたはパスワードが違います。」(Invalid Email or password.) の
alertFlashメッセージが表示されます。 - ログイン済みの場合の挙動
-
もし、既にログインしている状態(例えば、サインアップ直後など)で
/admin/sign_inにアクセスしようとすると、Devise は自動的にルートパスなどにリダイレクトし、“You are already signed in.” (すでにログインしています。) というalertFlashメッセージを表示します。
これはエラーではなく、Devise の正常な動作であり、二重ログインを防ぐための挙動です。
サインイン機能を試す際は、一度ログアウトしてからアクセスするか、シークレットモード/プライベートブラウジングのウィンドウで試すと良いでしょう。
- 3. サインアウト用リンク/ボタンの設置
-
ログアウト機能を使うには、ログアウト処理を行うパス (
/admin/sign_out) へ DELETEメソッドでリクエストを送る必要があります。
管理画面共通ヘッダー (app/views/shared/_header.html.erb) などにリンクまたはボタンを設置します。<header class="navbar navbar-expand-md d-print-none"> <div class="container-xl"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#sidebar-menu" aria-controls="sidebar-menu" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3"> <%= link_to admin_root_path, class: "navbar-brand" do %> MyApp <% end %> </h1> <div class="navbar-nav flex-row order-md-last"> <div class="nav-item"> <%= button_to "ログアウト", destroy_user_session_path, method: :delete, class: "nav-link", form: { class: 'd-inline' } %> </div> </div> </div> </header>destroy_user_session_pathは/admin/sign_outへのルーティングヘルパーです。- 重要:
button_toにmethod: :deleteを指定するか、link_toにdata: { turbo_method: :delete }を指定しないと、GETリクエストになってしまい正しくログアウトできません。
- 4. ログアウト実行
-
ログインした状態で、設置したログアウトリンク/ボタンをクリックします。
- 5. 結果確認
-
成功すると、デフォルトでルートパスにリダイレクトされ、「ログアウトしました。」(Signed out successfully.) の
noticeFlashメッセージが表示されます。
これで、ログインとログアウトの基本的なフローも動作することが確認できました。
Step 4: Deviseヘルパーで認証状態を活用する
Deviseは、ビューやコントローラーで認証状態を簡単に扱えるように、いくつかの便利なヘルパーメソッドを提供します。これらを使ってアプリケーションをより機能的にしましょう。
authenticate_user! : コントローラーでのアクセス制御
これはコントローラー内 (主に before_action として) で使用し、ログインしていないユーザーからのアクセスを拒否(ログインページへリダイレクト)するためのメソッドです。管理画面全体など、特定のエリアをログイン必須にしたい場合に非常に役立ちます。
- 実装例: 管理画面全体をログイン必須にする
-
# app/controllers/admin/base_controller.rb class Admin::BaseController < ApplicationController layout 'admin' before_action :authenticate_user! endこの1行を追加するだけで、
/admin配下の(Admin::BaseControllerを継承している)全てのページは、ログインしていないユーザーがアクセスしようとすると自動的にログインページ (/admin/sign_in) へリダイレクトされるようになります。
user_signed_in? と current_user : ビューでの表示切り替えとユーザー情報表示
- user_signed_in?
-
ユーザーが現在ログインしているかどうかを
true/falseで返します。ビューファイル内で条件分岐によく使われます。 - current_user
-
現在ログインしているユーザーの
Userモデルオブジェクトを返します。ログインしていない場合はnilを返します。ユーザーの名前やメールアドレスなどを表示するのに使います。 - 実装例: 管理画面ヘッダーのナビゲーションを完成させる
-
<%# app/views/layouts/admin.html.erb のヘッダー部分の例 %> <header class="navbar navbar-expand-md d-print-none"> <div class="container-xl"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#sidebar-menu" aria-controls="sidebar-menu" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3"> <%= link_to admin_root_path, class: "navbar-brand" do %> MyApp <% end %> </h1> <div class="navbar-nav flex-row order-md-last"> <% if user_signed_in? %> <%# --- ログインしている場合の表示 --- %> <div class="nav-item dropdown"> <a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown" aria-label="Open user menu"> <div class="d-none d-xl-block ps-2"> <%# current_user を使ってメールアドレス表示 %> <div><%= current_user.email %></div> <div class="mt-1 small text-muted">ログイン中</div> </div> </a> <%# ドロップダウンメニュー %> <div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow"> <%= link_to "アカウント設定", edit_user_registration_path, class: "dropdown-item" %> <%# /admin/account %> <div class="dropdown-divider"></div> <%= button_to "ログアウト", destroy_user_session_path, method: :delete, class: "dropdown-item" %> </div> </div> <% end %> </div> </div> </header>if user_signed_in?でログイン状態をチェックし、表示判定をしています。- ログイン中は
current_user.emailでメールアドレスを取得して表示しています。
これらのヘルパーを使うことで、認証状態に基づいた動的なページを簡単に構築できます。
まとめと次回予告
第2回では、Devise を使ったアプリケーションで、ユーザーが実際にサインアップ、サインイン、サインアウトできることを確認しました。また、Devise が提供する user_signed_in?, current_user, authenticate_user! といった基本的なヘルパーメソッドを使い、ビューの表示を切り替えたり、コントローラーでアクセス制御を行ったりする具体的な方法を学びました。
これで、あなたの Rails アプリケーションは動作する認証機能の基盤を持つことになりました。しかし、現状では Devise の認証画面はデフォルトのままで、管理画面のレイアウトも適用されていません。
次回(第3回) は、この認証画面の見た目を改善します。具体的には、Devise の認証画面(サインイン、サインアップ等)に管理画面の Tabler レイアウト (admin.html.erb) を適用する方法と、rails g devise:views コマンドで生成したビューファイルを編集してフォーム等の見た目を Tabler デザインにカスタマイズする手順を詳しく解説します。より洗練された認証画面を目指しましょう!



