はじめに
つぎにつくる予定のWebアプリでは、認証(ログイン)機能を実装しようと思っています。そこで認証機能を実装するためのgemで有名な『devise』の最低限の動作確認をしてみました。
環境は以下の通りです💡
- Ruby 2.6.3
- Rails 6.0.0
- devise 4.7.1 (現時点の最新バージョン)
完成イメージ
この記事の通りに進めると、以下のサンプルアプリが完成します。
トップページ(未ログイン状態)
ログイン画面
ログインするとユーザーページ表示
トップページ(ログイン状態)
ログアウトすると元に戻ります。
実装
1.rails newする
Rails6.0.0
でアプリを新規作成します。
rails _6.0.0_ new gem-devise-sample
トップページが表示されることを確認します。
2.devise をインストールする
Gemfileに以下を記述し、bundle install
。
# Gemfile gem 'devise'
続けて、以下のコマンドでdeviseの設定ファイルを作成します。
$ rails g devise:install
3.devise対応のUserモデルを生成する
Userモデルをつくります。以下のコマンドでdevise対応のUserモデルを生成。
$ rails g devise User
以下のマイグレーションファイルが生成されるので、rails db:migrate
でマイグレーションを実行。
コメントアウトされているカラムがあるが、今回は最低限の動作確認のみのため、そのままにしておきます。
# frozen_string_literal: true class DeviseCreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable # t.integer :sign_in_count, default: 0, null: false # t.datetime :current_sign_in_at # t.datetime :last_sign_in_at # t.string :current_sign_in_ip # t.string :last_sign_in_ip ## Confirmable # t.string :confirmation_token # t.datetime :confirmed_at # t.datetime :confirmation_sent_at # t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts # t.string :unlock_token # Only if unlock strategy is :email or :both # t.datetime :locked_at t.timestamps null: false end add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true # add_index :users, :confirmation_token, unique: true # add_index :users, :unlock_token, unique: true end end
この時点で、http://localhost:3000/users/sign_inを開くと最低限のログインページができています。
しかし、この状態だと認証後のリダイレクト先ページがRailsのデフォルトページ(Yay! You’re on Rails!の画面)になっているので、 リダイレクト先ページをユーザー個人のプロフィールページに変更します。
4.トップページをつくる
Pagesコントローラーをindex、showアクションつきで生成。
$ rails g controller Pages index show
ルーティングを設定をします。rootを先ほど生成したpages#index
に。なお、devise_for :users
はdevise対応のUserモデルを生成した時点で自動で設定されます。
# route.rb Rails.application.routes.draw do root 'pages#index' get 'pages/show' devise_for :users end
トップページのビューを編集します。今回は、ログイン状態によって、表示するリンクが切り替わるようにしたいと思います。user_signed_in?
でログイン状態を判定し、表示するリンクを切り替えます。
routes.rbに設定されたdevise_for :users
により、‘new_user_session_path‘や‘destroy_user_session_path‘など、devise用の名前付きルートが使えるようになっているので、その名前付きルートを使ってリンクを記述します。
<!-- index.html.erb --> <h1>トップページ</h1> <p>Find me in app/views/pages/index.html.erb</p> <% if user_signed_in? %> <%= link_to 'ログアウト', destroy_user_session_path, method: :delete %> <% else %> <%= link_to 'サインアップ', new_user_registration_path %> <%= link_to 'ログイン', new_user_session_path %> <% end %>
これで、ログイン状態によってリンクが切替わるようになりました。
5.認証後のリダイレクト先をユーザーページにする
Devise::Controllers::Helpers
のafter_sign_in_path_for
メソッドをオーバーライドすることで、認証後のリダイレクト先をカスタマイズできます。
# application.rb def after_sign_in_path_for(resource) "/user/#{current_user.id}" end
※current_userで現在ログインしているユーザー情報を取得できる。
ユーザーページのビューを編集します。ログインユーザーのメールアドレスを表示するようにしてみました。
<!-- show.html.erb --> <h1>ユーザーページ</h1> <div> あなたのメールアドレス:<%= current_user.email %> </div> <div> <%= link_to '戻る', root_path %> </div>
さいごに、ユーザーページのルーティングを編集。
# route.rb Rails.application.routes.draw do root 'pages#index' get "user/:id", :to => "pages#show" # この1行を編集 devise_for :users end
これで完成😤
ログインするとそのユーザーのページが開きます。
おわりに
ソースコードはこちらです💁♂️
サインインやサインアップページのビューや、動作をカスタマイズするにはrails g devise:views users
やrails g devise:controllers users
をしてdevise対応のコントローラーやビューを生成する必要があるようです。今回は最低限の動作確認が目的のため、そこまでは手を出しませんでした。
サンプルアプリをつくるくらいなら簡単ですが、deviseは多機能で、使いこなすのは一筋縄ではいかなそう、という印象を受けました。まあ、それでもゼロから認証機能をつくるよりはよっぽど簡単なのですが。