deviseを利用することで簡単に認証機能をRailsアプリケーションに構築できます。
今回はdeviseをインストールする手順について紹介します。
- deviseのセットアップ手順について理解する
- メールアドレス・パスワードを利用した認証の実装方法について理解する
- 認証情報を保存しているセッションの実態について理解する
目次
今回実装する内容について
deviseを利用するとさまざまなことができますが、今回の記事はdeviseのインストール手順が焦点のため、認証はシンプルな実装にします。
- メールアドレスとパスワードを利用してサインアップ・サインインできるアプリケーションを作成
- サインアップ・サインイン・サインアウト後はルート(/)へ遷移させる
- メール認証、ログイン状態の記憶、パスワードの変更などは実装しない
gemのインストール
devise gemをインストールします。
Gemfile
gem 'devise'
Gemfile編集後、bundle installを実行します。
$ bundle install
deviseのセットアップ
deviseの初期設定をするジェネレータ(devise:install
)を実行します。
$ rails generate devise:install
Running via Spring preloader in process 270
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Depending on your application's configuration some manual setup may be required:
1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.
* Required for all applications. *
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
* Not required for API-only Applications *
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
* Not required for API-only Applications *
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
* Not required *
===============================================================================
devise:install
を実行すると、deviseの設定ファイル(config/initializers/devise.rb
、config/locales/devise.en.yml
)の生成と、セットアップ手順の表示がされます。
コンソールの出力からもわかるように、deviseのセットアップ手順は以下の通りです。
- デフォルトURLの設定
- ルートURLの作成
- フラッシュメッセージの作成
- deviseに関するビューの作成
以下ではそれぞれの項目について説明します。
デフォルトURLの設定
各環境(developmentやproduction)で利用するデフォルトのURLを設定します。
たとえば、Action Mailerを利用して認証やパスワードリセットのメールを送信する場合、以下のような設定を追加します。
config/environments/development.rb
config.action_mailer.default_url_options = { host: Settings.host_name }
config/settings/development.yml
host_name: localhost:3000
今回の場合はデフォルトURLの設定は不要です。
ルートURLの作成
deviseでは、サインアップ・サインイン・サインアウト後はデフォルトでルート(/)へ遷移します。
deviseのデフォルトの設定を利用する場合、ルート画面を作成する必要があります。
今回は例としてhome#index
をルートURLに設定します。
ルーティングを追加します。
config/routes.rb
root to: 'home#index'
コントローラとビューを作成します。
$ rails g controller Home index
フラッシュメッセージの作成
サインアップやサインアウトの結果をフラッシュメッセージとして表示したい場合はレイアウトを編集します。
今回フラッシュメッセージの実装は行わないので説明を省略します。
deviseに関するビューの作成
deviseに関するビューを作成します。
devise:views
でサインアップやサインインなど、認証に必要な画面が一括で作成できます。
$ rails g devise:views
invoke Devise::Generators::SharedViewsGenerator
create app/views/devise/shared
create app/views/devise/shared/_error_messages.html.erb
create app/views/devise/shared/_links.html.erb (リンク用パーシャル)
invoke form_for
create app/views/devise/confirmations
create app/views/devise/confirmations/new.html.erb (認証メールの再送信画面)
create app/views/devise/passwords
create app/views/devise/passwords/edit.html.erb (パスワード変更画面)
create app/views/devise/passwords/new.html.erb (パスワードを忘れた際、メールを送る画面)
create app/views/devise/registrations
create app/views/devise/registrations/edit.html.erb (ユーザー情報変更画面)
create app/views/devise/registrations/new.html.erb (ユーザー登録画面)
create app/views/devise/sessions
create app/views/devise/sessions/new.html.erb (ログイン画面)
create app/views/devise/unlocks
create app/views/devise/unlocks/new.html.erb (ロック解除メール再送信画面)
invoke erb
create app/views/devise/mailer
create app/views/devise/mailer/confirmation_instructions.html.erb (メール用アカウント認証文)
create app/views/devise/mailer/email_changed.html.erb
create app/views/devise/mailer/password_change.html.erb (メール用パスワード変更完了文)
create app/views/devise/mailer/reset_password_instructions.html.erb(メール用パスワードリセット文)
create app/views/devise/mailer/unlock_instructions.html.erb (メール用ロック解除文)
モデルの作成
認証機能を利用するモデルを作成します。
たとえばUserモデルでdeviseの認証機能を利用する場合は以下のコマンドを実行します。
$ rails g devise User
invoke active_record
create db/migrate/20200322122835_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
モデルの編集
rails g devise [モデル名]
を実行するとdevise
という項目の付与されたモデルファイルが作成されます。利用するdeviseの機能(モジュール)のみを設定するように編集します。
各モジュールと概要は以下の通りです。1
モジュール | 概要 |
---|---|
database_authenticatable | サインイン時のパスワードをハッシュ化して保存する |
omniauthable | OmniAuthのサポート機能を提供。SNS認証を実装する場合に利用する |
confirmable | メール認証の機能を提供 |
recoverable | パスワードをリセットの機能を提供 |
registerable | ユーザーのサインアップ、アカウントの編集や破棄の機能を提供 |
rememberable | 認証情報を保存する機能を提供 |
trackable | サインイン回数、タイムスタンプ、IPアドレスを追跡する機能を提供 |
timeoutable | 一定時間活動していないアカウントのセッションを破棄機能を提供 |
validatable | Emailやパスワードのバリデーションを提供します。 |
lockable | 一定回数サインインを失敗するとアカウントをロックする機能を提供 |
今回はdatabase_authenticatable
とregisterable
を利用するため、以下のように修正しました。
app/models/User.rb
class User < ApplicationRecord
- devise :database_authenticatable, :registerable,
- :recoverable, :rememberable, :validatable
+ devise :database_authenticatable, :registerable
end
マイグレーションファイルの編集
rails g devise [モデル名]
を実行すると[日にち]_devise_create_[モデル名].rb
という名前のマイグレーションが作成されます。
利用するdeviseモジュールに応じてファイルを編集します。
今回はdatabase_authenticatable
とregisterable
を利用するので、マイグレーションファイルは以下のようになります。
# 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: ""
t.timestamps null: false
end
add_index :users, :email, unique: true
end
end
マイグレーションの実行
マイグレーションファイル編集後、マイグレーションを実行します。
$ rails db:migrate
動作確認
deviseの認証機能が正常に動作しているか確認します。
レイアウトファイルの編集
認証状態を画面から確認できるようにするため、レイアウトファイルを編集します。
app/views/layouts/home.html.erb
<!DOCTYPE html>
<html>
<head>
<title>SimpleDevise</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<header>
<nav>
<% if user_signed_in? %>
<%= "こんにちは#{current_user.email}さん" %>
<%= link_to 'ログアウト', destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'サインアップ', new_user_registration_path %>
<%= link_to 'ログイン', new_user_session_path %>
<% end %>
</nav>
</header>
<%= yield %>
</body>
</html>
サインアップの確認
Railsアプリケーションを再起動すると、localhost:3000/users/sign_up
で以下の画面が表示されます。
メールアドレスとパスワードを入力後ルート画面に遷移し、ヘッダにサインアップで利用したメールアドレスが記載されていればOKです。
認証情報の確認
deviseの認証情報はセッションで管理されています。
Railsアプリケーションではセッション情報はデフォルトでCookieに保存されています。
Cookieを確認すると、_[アプリケーション名]_session
というセッション情報が保存されていることがわかります。
今回はアプリケーション名をsimple_devise
としたので、_simple_devise_session
という名前のセッションが保存されています。
セッション情報をもとに認証が行われているため、_[アプリケーション名]_session
を削除してブラウザをリロードするとサインアウト状態になります。
まとめ
- 『devise:install』で設定ファイル作成
- 『devise:views』でビュー作成
- 『devise モデル名』でモデル作成
- モデル・マイグレーションのファイルを編集
- マイグレーション実行
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!
Rubyのオススメ参考書
- https://github.com/heartcombo/devise ↩