【Rails5】deviseを使ってログイン機能を作る
こんにちは。かくすけです。
最近家で育てているカイコの卵が一気に孵化を初めて春の訪れを感じるこの頃です。
今回はかくすけWebサイトにログイン機能を追加していきます!
ログインした管理者だけが下の画像でいう③や④の内容を編集できるようにします。
手順
deviseというgemを使います。 このgemはRailsでログインするときに使う定番のgemですね。
参考にしたページ [*Rails*] deviseの使い方(rails5版) - Qiita
Gemfileにdeviseを追加
Gemfile
# ログイン機能実装
gem 'devise'
Gemfileに追加したdeviseをインストールするために「bundle install」を実行します。
$ bundle install
環境で初めてdeviseを使う場合は次のコマンドも実行しましょう。
rails g devise:install
ログイン用モデルの追加
ログイン情報を持つAdminというモデルを作成します。
(Adminの部分はお好みのモデル名にしてOKです。)
$ bundle exec rails g devise admin
以下のように表示され、いくつかのファイルが生成されます。
invoke active_record
create db/migrate/20190413095444_devise_create_admins.rb
create app/models/admin.rb
invoke test_unit
create test/models/admin_test.rb
create test/fixtures/admins.yml
insert app/models/admin.rb
route devise_for :admins
次のようなマイグレーションファイルが作られます。 ./db/migrate/20190413095444_devise_create_admins.rb
deviseの場合メールアドレスでのログインがデフォルトですが 私はメールアドレス以外の文字列でログインできるようにしたいのでちょっとこのファイルを編集します。
# frozen_string_literal: true
class DeviseCreateAdmins < ActiveRecord::Migration[5.2]
def change
create_table :admins do |t|
## Database authenticatable
t.string :email, default: "" # ここを変更。メールアドレスが空でも登録できるように。
t.string :login_name, 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 :admins, :email, unique: true
add_index :admins, :login_name, unique: true # ここを追加
add_index :admins, :reset_password_token, unique: true
# add_index :admins, :confirmation_token, unique: true
# add_index :admins, :unlock_token, unique: true
end
end
login_nameを使ってログインさせることにします。
メールアドレスは消してもいいのですが、deviseデフォルトのカラムということで別部分で影響が出そうなので一応残してます。
ただし、"null: false"の設定を消すことでメールアドレスが空でも登録できるようにしました。
変更を保存してdb:migrateします。
$ bundle exec rake db:migrate
マイグレートが実行され、次のように表示されます。
== 20190413095444 DeviseCreateAdmins: migrating ===============================
-- create_table(:admins)
-> 0.0080s
-- add_index(:admins, :email, {:unique=>true})
-> 0.0320s
-- add_index(:admins, :login_name, {:unique=>true})
-> 0.0071s
-- add_index(:admins, :reset_password_token, {:unique=>true})
-> 0.0078s
== 20190413095444 DeviseCreateAdmins: migrated (0.0550s) ======================
画面の確認
ちゃんとdeviseが正しく動いているか確認してみましょう
railsサーバーを起動します。
$ bundle exec rails s -b 0.0.0.0
ブラウザでログインページにアクセスします。
URLは"http://~~/admins/sign_in"です。
URLは環境に合わせて読みかえてください。
正しく動いていれば、次のようなページが表示されます。
ログインしていないと入れないページを設定する
無事にdeviseを導入することができました!
しかしこのままではログインしていなくても結局すべてのページにアクセスすることができてしまいます。
ログインしていないと入れないページを作りましょう。
ここで、deviseを入れることで使えるようになる便利なヘルパーメソッドがいくつかあります
参考: Rails deviseで使えるようになるヘルパーメソッド一覧 - Qiita
この中でログインしていないと入れないようにするのが"authenticate_user!"です。
私の場合はモデル名を"user"ではなく"admin"にしているので、"authenticate_admin!"ですね。
このヘルパーをcontrollerのbefore_actionに設定します。
私の場合、Serviceモデル関連のページのアクセスを制限したいので、"services_controller.rb"に追記します。
app/controllers/services_controller.rb
class ServicesController < ApplicationController
before_action :authenticate_admin! # ここを追加
before_action :set_service, only: [:edit, :update, :destroy]
# GET /services
def index
@services = Service.all
end
....
これを保存して"http://~~/services"にアクセスします。
すると、強制的にログインページが表示されます!
アカウントを作ってみる
servicesのページにアクセスできないことが確認できました!
ただ、これってひょっとしたらログインしていてもアクセスできないのでは・・・?
確認用のアカウントを作成して試してみましょう。
ログインページの"Sign up"リンクをクリックします。
するとアカウント作成用のページが表示されます。
メールアドレスとパスワードを適当に入力します。パスワードは同じものを2回入力します。
メールアドレスは実際に使えるものである必要はありません。
(もちろん設定次第ではてきとーなメールアドレスを禁止したりもできますよ!)
"Sign up"ボタンを押すとアカウントが作成され、自動的にログインされます。
ログインしたので"http://~~/services"がちゃんと表示されました!
これで最低限のログイン機能が実装できました! こんなに簡単に実装できちゃうなんて、deviseには感謝ですね!
ちなみにdeviseのデフォルト設定だとロードバランサーがうまく動かなかったり
バージョンによってはaxlsxというExcelファイルを生成するgemと相性が悪かったりするので注意が必要です。
そのあたりはまたそのあたりの対処をするときにまとめますね!
参考:
[*Rails*] deviseの使い方(rails5版) - Qiita
Rails deviseで使えるようになるヘルパーメソッド一覧 - Qiita