Ruby on Rails での認証(Deviseライブラリ)

前回から引き続き、Ruby on Rails での認証を調べていると頻繁にdeviseライブラリに関する記述を見かけることが多かったので触ってみます。

参考にしたのは以下のページ

原文を見ながら、手助けとして Qiita のページを見てみます。
ちなみに見つけたのは Qiita のページが先でした。

目次

前提条件

認証について作成する前に前回同様に scaffold で Records テーブルと各コントローラを作っておいた。

1
2
rails g scaffold Resords title:string body:string level:integer
rails db:migrate

device を導入

0.Gemfile 編集

Gemfile に以下の記述を追加する。

Gemfile
1
gem 'devise'

1.インストール

コンソールで以下を実行

1
>bundle install

コマンド実行時末尾にUse `bundle info [gemname]` to see where a bundled gem is installed.と記述があったので、その通りにすると以下のようにパッケージ情報が表示された。

1
2
3
4
5
6
>bundle info devise
* devise (4.6.2)
Summary: Flexible authentication solution for Rails with Warden
Homepage: https://github.com/plataformatec/devise
Path: C:/Ruby25-x64/lib/ruby/gems/2.5.0/gems/devise-4.6.2

2.ジェネレータ実行

コンソールで以下を実行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
>rails generate devise:install
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

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.

2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:

root to: "home#index"

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>

4. You can copy Devise views (for customization) to your app by running:

rails g devise:views

===============================================================================

この後することを示しているので、その通り進めてゆく

3.環境設定を実施

[アプリケーションルート]/config/environments/development.rb を編集する

[アプリケーションルート]/config/environments/development.rb
1
2
3
4
5
Rails.application.configure do
#~省略~
#末尾に以下を追加
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end

4.ルートを変更

2.ジェネレータ実行での内容で、以下を例にルートを変更するように指示されている

1
root to: "home#index"

なので、scaffold で用意していたアクションを利用して

1
root to: "record#index"

5.フラッシュメッセージがあることを確認

フラッシュメッセージがこの時点では何かはわからないが、
以下が[アプリケーションルート]\app\views\layouts\application.html.erb に必要だそう。

1
2
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

以下のように[アプリケーションルート]\app\views\layouts\application.html.erb を書き換えた。

[アプリケーションルート]\app\views\layouts\application.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<title>App4</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>

<body>
<!--以下2行を追加-->
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
</body>
</html>

6.Devise のビューを作成

カスタマイズするなら、という条件付きではあったのだけどやってみる。
以下をコンソールで実行

1
>rails g devise:views

[アプリケーションルート]\app\views\devise 以下にファイルが作成される。

7.認証用のモデルの作成と展開

公式ではrails generate devise MODELという記述で説明されている。
ここは他の参考サイトに倣ってrails generate devise Userとする。

1
2
>rails generate devise User
>rails db:migrate

8.フィルタの設定

before_action :authenticate_user!を使用することができると解説されているので、追加してみる。

[アプリケーションルート]\app\controllers\records_controller.rb
1
2
3
4
class RecordsController < ApplicationController
before_action :authenticate_user!
# 以下省略
end

試しにこの時点でサーバー起動して、localhost:3000にアクセスすると、
ルーティング設定した”record#index”ではなく、http://localhost:3000/users/sign_inにリダイレクトされ、以下のようにログイン要求されるようになる。

サインアップするとルーティング設定した”record#index”にリダイレクトされる。
以下の画面になる。

ここで初めてフラッシュメッセージの内容がわかった。
ページ更新をすると「Welcome! you ~」が表示されない。その時だけ一回表示される。
故にフラッシュメッセージ。

ここまででログインできる Web サイト・アプリが完成

9.ログアウトできるようにする。

  • user_signed_in?ヘルパーを使用することで、ログイン済みか判断できる。
  • current_user でログインしているユーザー情報が取得できる。
    [アプリケーションルート]\db\migrate[数字列]_devise_create_users.rb
    を参照すると、email カラムがあるので、current_user.email でログインしているユーザーの登録メールアドレスが参照できる。

以上を踏まえて、[アプリケーションルート]\app\views\layouts\application.html.erb を編集してみる。

[アプリケーションルート]\app\views\layouts\application.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<header>
<% if user_signed_in? %>
LogOnUser:<%= current_user.email %>
<%= link_to 'SignOut', destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'SingUp', new_user_registration_path %>
<%= link_to 'SignIn', new_user_session_path %>
<% end %>
</header>
<!--以下省略-->
</body>

アクセスしログインすると、以下のようにログインユーザーのメールアドレスと SignOut が表示されるようにできた。

確認

devise_for

作成後に動作確認とコードの見比べをしていたところ、
ルーティングで記述が増えていた

[アプリケーションルート]\config\routes.rb
1
2
devise_for :users
# 以下省略

8.でログイン時http://localhost:3000/users/sign_inにリダイレクトされていたけれど、
[アプリケーションルート]\app\views\users が無いのに動作している秘密はこのあたりにある。

認証不要のページの設定

basic 認証を設定したとき同様に、defore_action の except オプションを使用する。

1
before_action :authenticate_user!, except: [:index,:show]

これで、/index と/show については認証不要になる。

参考にさせてもらった記事だと、twitter 連携をしていたりするのだけれど、
過去に Twitter Developer も申請が通らなかったことがあるので、Google 認証下やってみたいところ。

さて連休だ。
移動中に積読を潰してこう。
Ruby on Rails Tutorialは連休中に始められるだろうか・・・。

ではでは。