LoginSignup
6
11

More than 5 years have passed since last update.

deviseを使ってみる

Last updated at Posted at 2016-09-22

Ruby on Railsの勉強を始めました。
deviseというユーザー認証系の便利なGemがあるとのことで、今回使用してみました。
ご参考にしていただければと思います。

準備

$ rails new rails_devise
$ cd rails_devise
$ bundle install --path=vendor/bundle

新規プロジェクトの作成と、初期のGemをインストールしました。
ついでにGitで管理もしたいので、Githubにリポジトリを作成しました。
SourceTreeとGithubでGitの練習環境をつくる

$ git init
$ git remote add origin git@github.com:naoki85/rails_devise.git
$ git add .
$ git commit -m "first commit"

ここでリモートブランチにREADME.mdを先に作成しているとpushするときに怒られるようです。
そのため、リモートのマスターブランチをマージします。

$ git pull origin master
# コンフリクトを解決
$ git add .
$ git commit -m "resolved conflict"
$ git push origin master

deviseのインストール

deviseをGemfileに追加します。

Gemfile
+ # Use Devise for Authentication
+ gem 'devise'

そしてインストールします。

$ bundle install

さて、ここからdeviseを実装していきます。
(参考資料:公式のGithub

$ rails generate devise:install

インストールすると、何やら注意文が出てきました。
以下のページの執筆者の方が日本語訳してくださっておりましたので、そちらに従って対応します。
[Rails] deviseの使い方

その前に、vendor/bundle以下のファイル.gitignoreに追加し、コミットさせないようにします。
(差分が見えづらくなるので。)

.gitignore
+ # Ignore bundler gems.
+ vendor/bundle

デフォルトURLの指定

今回はローカル環境で試すだけなので、localhost:3000を指定します。

config/environments/development.rb
+ # mailer setting
+ config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

root_urlの指定

http://localhost:3000にアクセスしたとき呼ばれるページの指定をします。
参考にさせていただいているページと同様、まだコントローラーも作成していなかったため、ここで作成します。

$ rails g controller Pages index show

これでコントローラーが作成できたので、routes.rbに記載します。

config/routes.rb
+ root 'pages#index'
+ get 'pages/show'

Flashメッセージの設定

Flashメッセージが表示される場所を追記します。
以下の文そのままで良いようです。

views/layouts/application.html.erb
<body>
+  <p class="notice"><%= notice %></p>
+   <p class="alert"><%= alert %></p>
  <%= yield %>
</body>

Viewの作成

Deviseの導入で追加されるViewは、以下のコマンドを実行しなければデザインを変更できないので、デザインをカスタマイズするためにも実行します。
[Rails] deviseの使い方

$ rails g devise:views

モデルの作成

devise用のモデルを作成し、マイグレーションを走らせます。
(モデル名は任意です。)

$ rails g devise Admin_User
$ rails db:migrate

マイグレーションファイルは以下のようになっております。
デフォルトでコメントアウトされている部分もオープンにできますが、今回はライトに作りたいため、デフォルトのままでいきます。

class DeviseCreateAdminUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :admin_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 :admin_users, :email,                unique: true
    add_index :admin_users, :reset_password_token, unique: true
    # add_index :admin_users, :confirmation_token,   unique: true
    # add_index :admin_users, :unlock_token,         unique: true
  end
end

また、モデルも同様に、最初から使用できるモジュールと、任意で設定するモジュールがあります。

admin_user.rb
class AdminUser < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

今回はデフォルトなので、初めから使用できる下記のモジュールを使用します。
(参考資料:Railsの第4世代認証エンジンDeviseのREADMEを翻訳してみた

モジュール名 役割
Database Authenticatable ユーザーがサインインする時に認証するためにパスワードをデータベースに暗号化し保存します。この認証は POST リクエストまたはBasic認証を通して行われます。
Registerable 登録プロセスを通してサインアップを処理します。また、アカウントを編集・削除できるようにします。
Recorverble パスワードをリセットし、リセットの指示を送ります。
Rememberable ユーザーを記憶するために、保存されたクッキーから、トークンを生成・消去を扱います。
Trackable サインインのカウント・タイムスタンプ・IPアドレスを計測します。
Validatable Eメールとパスワードによる確認を提供します。これは、オプションでカスタマイズできるので、あなた専用の確認を定義できます。

ここまでで、とりあえずrails sでローカルサーバーを起動させ確認してみると、特に何もありません。(当たり前ですが。。。)
スクリーンショット 2016-09-22 19.20.03.png

ヘルパーの実装

ユーザーがログインしていなければリダイレクトさせるのは、下記をpages_controller.rbに追記します。

controllers/pages_controller.rb
class PagesController < ApplicationController
+  before_action :authenticate_admin_user!

  def index
  end

  # ...

再度、ページにアクセスしてみると、下記のようにリダイレクトされます。
スクリーンショット 2016-09-22 20.16.11.png
このビューは、views/devise/sessions/new.html.rbになります。
rails routesで確認できます。)

とりあえず新規登録をしてみると、下図のようにログインまでしてくれます。
ただ、ログインしていないと無条件でリダイレクトされるのも微妙なので、indexにはログインしていなくてもアクセスできるようにし、showにはログインしていないとアクセスできないようにします。
スクリーンショット 2016-09-22 20.30.36.png

showだけログインしていないとアクセスできないようにする

controllers/pages_controller.rb
class PagesController < ApplicationController
-  before_action :authenticate_admin_user!
+  before_action :authenticate_admin_user!, only: [:show]

  def index
  end

  # ...

ログイン後のリダイレクト先を変更する

after_sign_in_path_forafter_sign_out_path_forで上書きしてしまうようです。
必ず呼ばれるapplication_controller.rbに記述します。
(参考資料:ログイン後にマイページに飛ばす:Rails devise

controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

+  def after_sign_in_path_for(resource)
+    pages_show_path
+  end
end

ログインとログアウトのリンクを設置する

ログインするのもログアウトするのもリンクがあると楽なので、簡単に設置してしまいます。

views/layouts/application.html.erb
<body>
+    <%= link_to 'Login', new_admin_user_session_path, method: :get %>
+    <%= link_to 'Logout', destroy_admin_user_session_path, method: :delete %>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>

    <%= yield %>
</body>

ログインしている場合としていない場合でリンクを出し分ける

他にも便利なヘルパーがあり、user_signed_in?でログインしているかどうかの結果を返してくれます。
(ただし、今回はモデル名をAdmin_Userにしたため、下記のサンプルの中ではadmin_user_signed_in?となっています。)
これで、ログインとログアウトのリンクを出し分けたいと思います。

views/layouts/application.html.erb
-    <%= link_to 'Login', new_admin_user_session_path, method: :get %>
-    <%= link_to 'Logout', destroy_admin_user_session_path, method: :delete %>
+ <% if admin_user_signed_in? %>
+     <%= link_to 'Logout', destroy_admin_user_session_path, method: :delete %>
+ <% else %>
+     <%= link_to 'Login', new_admin_user_session_path, method: :get %>
+ <% end %>

ログインしているユーザーの情報を取得

こちらはcurrent_userでオブジェクトを取得できます。
(ただし、今回はモデル名をAdmin_Userにしたため、下記のサンプルの中ではcurrent_admin_userとなっています。)
また、user_sessionで現在のセッション情報を取得できるようですが、初期状態は空っぽです。
(何も入れていないので当たり前ですが。。。)

views/pages/show.html.erb
-<h1>Pages#show</h1>
-<p>Find me in app/views/pages/show.html.erb</p>
+<h1>Hi!!<%= current_admin_user.email %>!!</h1>
+<p><%= debug(admin_user_session) %></p>

最後に

今回、モデル名をUserではなく、Admin_Userにしたため、基本ヘルパーのuserの部分をadmin_userにする必要がありました。
モデル名をUser以外にしようとしている方は要注意です。

ビューが少し寂しいので、Bootstrapで少し整えたいと思います。

6
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
11