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に追加します。
+ # Use Devise for Authentication
+ gem 'devise'
そしてインストールします。
$ bundle install
さて、ここからdevise
を実装していきます。
(参考資料:公式のGithub)
$ rails generate devise:install
インストールすると、何やら注意文が出てきました。
以下のページの執筆者の方が日本語訳してくださっておりましたので、そちらに従って対応します。
([Rails] deviseの使い方)
その前に、vendor/bundle
以下のファイル.gitignore
に追加し、コミットさせないようにします。
(差分が見えづらくなるので。)
+ # Ignore bundler gems.
+ vendor/bundle
デフォルトURLの指定
今回はローカル環境で試すだけなので、localhost:3000
を指定します。
+ # 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
に記載します。
+ root 'pages#index'
+ get 'pages/show'
Flashメッセージの設定
Flashメッセージが表示される場所を追記します。
以下の文そのままで良いようです。
<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
また、モデルも同様に、最初から使用できるモジュールと、任意で設定するモジュールがあります。
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
でローカルサーバーを起動させ確認してみると、特に何もありません。(当たり前ですが。。。)
ヘルパーの実装
ユーザーがログインしていなければリダイレクトさせるのは、下記をpages_controller.rb
に追記します。
class PagesController < ApplicationController
+ before_action :authenticate_admin_user!
def index
end
# ...
再度、ページにアクセスしてみると、下記のようにリダイレクトされます。
このビューは、views/devise/sessions/new.html.rb
になります。
(rails routes
で確認できます。)
とりあえず新規登録をしてみると、下図のようにログインまでしてくれます。
ただ、ログインしていないと無条件でリダイレクトされるのも微妙なので、index
にはログインしていなくてもアクセスできるようにし、show
にはログインしていないとアクセスできないようにします。
showだけログインしていないとアクセスできないようにする
class PagesController < ApplicationController
- before_action :authenticate_admin_user!
+ before_action :authenticate_admin_user!, only: [:show]
def index
end
# ...
ログイン後のリダイレクト先を変更する
after_sign_in_path_for
やafter_sign_out_path_for
で上書きしてしまうようです。
必ず呼ばれるapplication_controller.rb
に記述します。
(参考資料:ログイン後にマイページに飛ばす:Rails devise)
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
+ def after_sign_in_path_for(resource)
+ pages_show_path
+ end
end
ログインとログアウトのリンクを設置する
ログインするのもログアウトするのもリンクがあると楽なので、簡単に設置してしまいます。
<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?
となっています。)
これで、ログインとログアウトのリンクを出し分けたいと思います。
- <%= 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
で現在のセッション情報を取得できるようですが、初期状態は空っぽです。
(何も入れていないので当たり前ですが。。。)
-<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で少し整えたいと思います。