[Rails]deviseでadmin認証を作る
はじめに
Deviseを使用してRailsアプリ内でユーザーモデルと認証を設定した場合、管理者(admin)用の独自のログインと管理画面を作成する手順をまとめてみました。
環境
Rails 7.0.4.3
ruby 3.2.1
前提
ユーザーテーブルにRole
カラムが作成されていることです。
bin/rails g migration AddRoleToUser role:integer
class User < ApplicationRecord
enum role: { general: 0, admin: 1 }
end
ルーティングを設定する
URLを/admin
から始めたいので設定します。
Rails.application.routes.draw do
devise_for :users, controllers: {
registrations: 'users/registrations', # ユーザー用のコントローラー
# 他のコントローラー設定
}
namespace :admin do
devise_scope :user do
get 'login', to: 'sessions#new'
post 'login', to: 'sessions#create'
delete 'logout', to: 'sessions#destroy'
end
end
end
devise_scope
devise_scope
は、Deviseが提供するルーティングの設定に関するメソッドです。Deviseはユーザー認証と関連するルーティングを自動的に生成しますが、特定のアクションやコントローラーに対してカスタムの設定を適用したい場合に devise_scope
を使用します。
通常、devise_scope
は、Deviseのルーティングに追加の設定やオプションを適用するために使用されます。例えば、特定のコントローラーを指定したり、カスタムのアクションを追加したり、特定のURLパスを割り当てたりする場合に利用します。
devise_scope :user do
get '/register', to: 'users/registrations#new'
post '/register', to: 'users/registrations#create'
get '/login', to: 'users/sessions#new'
post '/login', to: 'users/sessions#create'
delete '/logout', to: 'users/sessions#destroy'
end
上記の例では、devise_scope
内でカスタムのルートを定義しています。ここでは、ユーザーの新規登録(/register
)、ログイン(/login
)、ログアウト(/logout
)に対してカスタムのURLパスを設定しています。
また、それぞれのルートは users/registrations
と users/sessions
コントローラー内のアクションと対応しています。これにより、デフォルトの Devise のルーティングに追加のカスタムルートを設定して、アプリケーションの要件に合わせてユーザー登録とセッション管理をカスタマイズできるようになります。
このように devise_scope
を使用することで、Deviseが提供するルーティングにカスタムの設定を組み込むことができます。カスタムルートの定義やルートの命名において、アプリケーションのニーズに合わせて調整することができます。
管理者用のコントローラーとビューを生成する
bin/rails generate devise:controllers admin
bin/rails generate devise:views admin
ロールカラムを許可する
deviseの許可するパラメーターにrole
を追加します。
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
# 管理者用のカラムを許可
devise_parameter_sanitizer.permit(:sign_up, keys: [:role])
devise_parameter_sanitizer.permit(:account_update, keys: [:role])
end
end
Admin::Base
コントローラーを作成する
ロールごとにアクセス権限を制御するためにBase
コントローラーを作成します。
class Admin::BaseController < ApplicationController
before_action :authenticate_user!
before_action :check_admin
private
def check_admin
unless current_user&.admin?
redirect_to root_path, alert: '権限がありません。'
end
end
end
レイアウトを宣言する
class Admin::BaseController < ApplicationController
layout 'admin'
end
管理者がログアウトしたら管理者用のログイン画面に遷移させたいのでafter_sign_out_path
ヘルパーメソッドを使って定義します。
class Admin::SessionsController < Devise::SessionsController
layout 'admin'
def after_sign_out_path_for(resource)
admin_login_path
end
end
レイアウトファイルを作成する
app/views/layouts/admin.html.erb
を作成します。
管理画面用のテンプレートパーシャル
app/views/admin/layouts/_header.html.erb
とapp/views/admin/layouts/_footer.html.erb
を作成し、adminレイアウトに追加します。
/admin/login
にアクセスするとadmin用のログイン画面を表示されていることを確認します。
20:26:36 web.1 | Started GET "/admin/login" for ::1 at 2023-08-13 20:26:36 +0900
20:26:36 web.1 | Processing by Admin::SessionsController#new as HTML
20:26:36 web.1 | Rendering layout layouts/admin.html.erb
20:26:36 web.1 | Rendering admin/sessions/new.html.erb within layouts/admin
20:26:36 web.1 | Rendered admin/shared/_links.html.erb (Duration: 1.0ms | Allocations: 468)
20:26:36 web.1 | Rendered admin/sessions/new.html.erb within layouts/admin (Duration: 4.2ms | Allocations: 2849)
20:26:36 web.1 | Rendered admin/layouts/_header.html.erb (Duration: 0.7ms | Allocations: 383)
20:26:36 web.1 | Rendered admin/layouts/_footer.html.erb (Duration: 0.3ms | Allocations: 101)
20:26:36 web.1 | Rendered layout layouts/admin.html.erb (Duration: 14.7ms | Allocations: 12907)
20:26:36 web.1 | Completed 200 OK in 18ms (Views: 16.5ms | Allocations: 14107)
管理画面のルートパスを作成する
管理者がログインしたらアプリのルートパスではなく、管理画面のルートパスに遷移させます。
Rails.application.routes.draw do
namespace :admin do
resources :dashboard, only: [:index]
root to: 'dashboard#index'
end
end
adminのルートを確認します。
Prefix Verb URI Pattern Controller#Action
admin_login GET /admin/login(.:format) admin/sessions#new
POST /admin/login(.:format) admin/sessions#create
admin_logout DELETE /admin/logout(.:format) admin/sessions#destroy
admin_root GET /admin(.:format) admin/dashboard#index
Dashboardコントローラーを作成する
Admin::Base
コントローラーを継承することにしましょう。
class Admin::DashboardController < Admin::BaseController
def index
end
end
ダッシュボードビューを作成する
app/views/admin/dashboard/index.html.erb
にダッシュボードのビューを作成します。
終わりに
ユーザーモデルに管理者(admin)用の独自のログインと管理画面を作成することができました。
Discussion