前回の記事ではRailsアプリにdevise gemをインストールしてセットアップしました。 今回は実際に認証機能付きモデルを追加し、ログイン機能を実装します。
実装は下記の手順で行います。
- 認証機能付きモデルの作成
- 認証機能用ビューの作成
- 認証機能用コントローラの作成
- ユーザ名表示、ログアウトボタン設置
- その他の追加設定
- 未ログインでログインページ以外を開けないようにする
- ログイン後のリダイレクト先を指定する
1. 認証機能付きモデルの作成
rails g devise モデル名単数形
で認証機能を追加するmodelを作成できます。
今回はUserモデルに認証機能を追加します。
$ rails g devise user Running via Spring preloader in process 78847 invoke active_record create db/migrate/20220825193835_devise_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml insert app/models/user.rb route devise_for :users
modelファイル、migrateファイルが追加されUserモデル用のルーティングが追加されます。
config/routes.rb
には次のような認証機能を使うためのルーティングが追加されます。
# config/routes.rb Rails.application.routes.draw do # 追加されるルーティング devise_for :users ...
追加されるルーティング一覧です。
$ rails route Prefix Verb URI Pattern Controller#Action new_user_session GET /users/sign_in(.:format) devise/sessions#new user_session POST /users/sign_in(.:format) devise/sessions#create destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy new_user_password GET /users/password/new(.:format) devise/passwords#new edit_user_password GET /users/password/edit(.:format) devise/passwords#edit user_password PATCH /users/password(.:format) devise/passwords#update PUT /users/password(.:format) devise/passwords#update POST /users/password(.:format) devise/passwords#create cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel new_user_registration GET /users/sign_up(.:format) devise/registrations#new edit_user_registration GET /users/edit(.:format) devise/registrations#edit user_registration PATCH /users(.:format) devise/registrations#update PUT /users(.:format) devise/registrations#update DELETE /users(.:format) devise/registrations#destroy POST /users(.:format) devise/registrations#create ...
app/models/user.rb
には使用するモジュールが追加されます。
使用するdeviseのモジュールの追加や削除はここで設定するようです。
[*Rails*] deviseの使い方(rails5版) - Qiita
# app/models/user.rb class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable end
migrateファイルへのカラム追加等が必要な場合はこのタイミングでファイルを修正します。
今回は全てデフォルトで進めます。
各ファイルの修正が終わったらmigrate
します。
$ rails db:migrate
rails s
でサーバを起動し追加された以下のルーティングへアクセスするとログイン機能の各ページの表示を確認できます。
users/sign_up
: サインアップusers/sign_in
: ログイン
以上で認証機能付きモデルの追加は完了です。
2. 認証機能用ビューの作成
deviseで作成したページ(ログインページ等)の表示で使用するviewファイルは自分のプロジェクトには存在しません(devise gemから読み込んでいるっぽい)。 このviewファイルを独自にカスタマイズしたい場合は自分のプロジェクト内にdeviseの表示に使うviewファイルを追加する必要があります。
rails g devise:views モデル名複数形
で認証機能付きモデルのviewファイルを追加できます(deviseのデフォルトのviewファイルのコピーが作成される)。
もし、deviseの認証機能で使用するviewファイルにカスタマイズしない場合はこの手順は不要です。
viewファイルの中身の変更は後回しにしてファイル追加と読み込みの設定のみ行います。
今回はUserモデルを指定してrails g devise:views
コマンドを実行し、app/views/users/
にdeviseの各モジュール毎のviewファイルを追加します。
ちなみに、モデルを指定しない場合はdeviseを使用する各モデル共通のviewファイルがapp/views/devise
に追加されます。
$ rails g devise:views users Running via Spring preloader in process 21582 invoke Devise::Generators::SharedViewsGenerator create app/views/users/shared create app/views/users/shared/_error_messages.html.erb create app/views/users/shared/_links.html.erb invoke form_for create app/views/users/confirmations create app/views/users/confirmations/new.html.erb create app/views/users/passwords create app/views/users/passwords/edit.html.erb create app/views/users/passwords/new.html.erb create app/views/users/registrations create app/views/users/registrations/edit.html.erb create app/views/users/registrations/new.html.erb create app/views/users/sessions create app/views/users/sessions/new.html.erb create app/views/users/unlocks create app/views/users/unlocks/new.html.erb invoke erb create app/views/users/mailer create app/views/users/mailer/confirmation_instructions.html.erb create app/views/users/mailer/email_changed.html.erb create app/views/users/mailer/password_change.html.erb create app/views/users/mailer/reset_password_instructions.html.erb create app/views/users/mailer/unlock_instructions.html.erb
作成したviewファイルを使って表示をするようにconfig/initializers/devise.rb
に設定を追加します。
config.scoped_views
をtrue
に設定します。
# config/initializers/devise.rb Devise.setup do |config| ... # ここのコメントアウトを外してtrueにする # config.scoped_views = false config.scoped_views = true
サーバーを再起動すると追加したviewファイルを参照するようになります。
3. 認証機能用コントローラ作成
viewファイル同様にdeviseで作成したページ(ログインページ等)の表示で使用するcontrollerファイルは自分のプロジェクトには存在しません。
deviseのコントローラをカスタマイズする場合はrails g devise:controller モデル名複数形
で認証機能付きモデルのcontrollerファイルを追加できます(deviseのデフォルトのcontrollerファイルのコピーが作成される)。
contlollerファイルの中身の変更と設定は後回しにてファイル追加のみを行います。
Userモデルを指定してrails g devise:controller
コマンドを実行するとapp/controllers/users/
に各モジュール毎のcontrollerファイルが追加されます。
$ rails generate devise:controllers users Running via Spring preloader in process 39155 create app/controllers/users/confirmations_controller.rb create app/controllers/users/passwords_controller.rb create app/controllers/users/registrations_controller.rb create app/controllers/users/sessions_controller.rb create app/controllers/users/unlocks_controller.rb create app/controllers/users/omniauth_callbacks_controller.rb =============================================================================== Some setup you must do manually if you haven't yet: Ensure you have overridden routes for generated controllers in your routes.rb. For example: Rails.application.routes.draw do devise_for :users, controllers: { sessions: 'users/sessions' } end ===============================================================================72681
app/models/user.rb
で有効化したモジュール毎にcontrollerファイルが作成されます。
例) デフォルトて有効化されているモジュールの場合のcontrollerファイル一覧
$ ls -1 app/controllers/users/ confirmations_controller.rb omniauth_callbacks_controller.rb passwords_controller.rb registrations_controller.rb sessions_controller.rb unlocks_controller.rb
作成したcontrollerファイルを修正することでdeviseの認証機能をカスタマイズできます。
controllerファイルに関してはviewファイルと異なり読み込み設定は不要ですが、controller毎にルーティングの設定が必要になります。 今回は記事ではこちらの設定は行いません。
heartcombo/devise: Flexible authentication solution for Rails with Warden.
4. ユーザ名表示、ログアウトボタン設置
全ページ共通のviewであるapp/views/application.html.erb
にユーザ名(デフォルトで用意されているemail
カラムの値)とログアウトボタンを設置します。
user_signed_in?
メソッドはサインインしていればtrue
、そうでなければfalse
を返す。current_user
メソッドでログインユーザの情報が取得する。
Rails deviseで使えるようになるヘルパーメソッド一覧 - Qiita
# app/views/application.html.erb <!DOCTYPE html> <html> ... <body> ... # 下記を追加 <% if user_signed_in? %> <p>User: <%= current_user.email %></p> <%= link_to 'Logout', destroy_user_session_path, method: :delete %> <% end %> <%= yield %> </body> </html>
if user_signed_in?
とすることでログイン時のみユーザ名(email)とログアウトボタンが表示されます。
5. その他の追加設定
ログイン機能に必須ではないですが以下の2つを設定しました。
- 未ログインでログインページ以外を開けないようにする
- ログイン後のリダイレクト先を指定する
未ログインでログインページ以外を開けないようにする
未ログインでログインページ以外のページにアクセスするとログインページ(users/sign_in
)にリダイレクトするように設定します。
deviseのauthenticate_モデル名単数!
メソッドでログイン済みユーザのみにアクセスを許可することができます。
全controllerで読み込まれるapp/controller/application_controller.rb
に設定を追加することで全ページへ設定を反映させます。
Rails deviseで使えるようになるヘルパーメソッド一覧 - Qiita
# app/controller/application_controller.rb ... class ApplicationController < ActionController::Base # 下記を追記 before_action :authenticate_user! end
ログイン後のリダイレクト先を指定する
deviseを使ったログイン認証後のリダイレクト先はデフォルトではアプリケーションのルート(/
)に設定されています。
config/routes.rb
のルートのURLをbooks#index
に変更することでログイン後のリダイレクト先を指定します。
# config/routes.rb Rails.application.routes.draw do # 下記を追加 root 'books#index' devise_for :users resources :books # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end
root
の追加を確認します。
$ rails routes Prefix Verb URI Pattern Controller#Action root GET / books#index books GET /books(.:format) books#index POST /books(.:format) books#create new_book GET /books/new(.:format) books#new edit_book GET /books/:id/edit(.:format) books#edit book GET /books/:id(.:format) books#show PATCH /books/:id(.:format) books#update PUT /books/:id(.:format) books#update DELETE /books/:id(.:format) books#destroy ...
ログイン後にbooks#index
ページにリダイレクトするようになりました。
devise gemを使ったログイン機能の実装は以上です。
まとめ
deviseを初めて触ってviewもcontlollerも見当たらないのにログイン機能が動作している事が気持ち悪かったですが、少しは理解が進んだ気がします。 一部の機能しか使えていないので少しずつ使い方に慣れていこうと思います。
参照
[*Rails*] deviseの使い方(rails5版) - Qiita
Railsにdeviseをインストールしてセットアップする - karlley's tech blog
heartcombo/devise: Flexible authentication solution for Rails with Warden.